堆排序是利用二叉堆的特性完成的排序。
二叉堆的特性
- 最大堆的堆顶是整个堆中最大的元素
- 最小堆的堆顶是整个堆中最小的元素
- 以最大堆为例,如果删除一个最大堆的堆顶(并不是完全删除,而是跟末尾节点交换位置,然后退出堆),经过自我调整,第二大的元素就会成为堆顶元素,往复 n-1次即可完成排序
思路
- 把无序数组构建成二叉堆。需要从小到大排序,则构成最大堆;反之,构成最小堆。
- 循环删除堆顶元素,替换到二叉堆的末尾,调整堆产生新的堆顶
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| public static void downAdjust(int[] array, int parentIndex, int length){ int temp = array[parentIndex]; int childIndex = 2 * parentIndex + 1; while(childIndex < length){ if(childIndex+1 < length && array[childIndex+1] > array[childIndex]) childIndex++;
if(temp >= array[childIndex]) break; array[parentIndex] = array[childIndex]; parentIndex = childIndex; childIndex = 2 * childIndex + 1; }
array[parentIndex] = temp; }
public static void heapSort(int[] array){ for(int i = array.length/2; i >=0; i--) downAdjust(array,i,array.length-1); for(int i = array.length-1; i > 0; i--){ int temp = array[i]; array[i] = array[0]; array[0] = temp;
downAdjust(array, 0 ,i); } }
|
时间复杂度
下沉调整的空间复杂度为O(logn),需要调整n次,因此时间复杂度为O(nlogn)
- 构建堆的时间复杂度为O(n),而不是(nlogn)
- 堆的插入和删除的时间复杂度都是O(logn)