堆排序(Heapsort)
堆排序
堆排序(Heapsort) 是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
算法描述
- 将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;
- 将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足R[1,2…n-1]<=R[n];
- 由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
算法分析
时间复杂度(平均) | 时间复杂度(最坏) | 时间复杂度(最好) | 空间复杂度 | 稳定性 |
---|---|---|---|---|
\(O(n\log_2 n)\) | \(O(n\log_2 n)\) | \(O(n\log_2 n)\) | \(O(1)\) | 不稳定 |
例子
![](https://img2022.cnblogs.com/blog/2758160/202202/2758160-20220223230849983-1036259871.png)
![](https://img2022.cnblogs.com/blog/2758160/202202/2758160-20220223231054164-2026631820.png)
![](https://img2022.cnblogs.com/blog/2758160/202202/2758160-20220223231103833-26618976.png)
![](https://img2022.cnblogs.com/blog/2758160/202202/2758160-20220223231108906-1710144205.png)
![](https://img2022.cnblogs.com/blog/2758160/202202/2758160-20220223231113891-199485185.png)
![](https://img2022.cnblogs.com/blog/2758160/202202/2758160-20220223231118022-522176144.png)
![](https://img2022.cnblogs.com/blog/2758160/202202/2758160-20220223231123496-441504339.png)
于是就得到了一个增数列
![](https://img2022.cnblogs.com/blog/2758160/202202/2758160-20220223231522863-1800729196.png)
动图演示
![](https://images.cnblogs.com/cnblogs_com/blogs/734424/galleries/2112342/o_220221110746_%E5%A0%86%E6%8E%92%E5%BA%8F.gif)
代码
Java
/*
* 堆排序(升序)
* @param array 待调整的堆
*/
public static void heapSort(int[] array) {
// 1.把无序数组构建成最大堆。
for (int i = (array.length-2)/2; i >= 0; i--) {
downAdjust(array, i, array.length);
}
System.out.println(Arrays.toString(array));
// 2.循环交换集合尾部元素到堆顶,并调节堆产生新的堆顶。
for (int i = array.length - 1; i > 0; i--) {
// 最后一个元素和第一元素进行交换
int temp = array[i];
array[i] = array[0];
array[0] = temp;
// 下沉调整最大堆
downAdjust(array, 0, i);
}
}
python
def buildMaxHeap(arr):
import math
for i in range(math.floor(len(arr)/2),-1,-1):
heapify(arr,i)
def heapify(arr, i):
left = 2*i+1
right = 2*i+2
largest = i
if left < arrLen and arr[left] > arr[largest]:
largest = left
if right < arrLen and arr[right] > arr[largest]:
largest = right
if largest != i:
swap(arr, i, largest)
heapify(arr, largest)
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
def heapSort(arr):
global arrLen
arrLen = len(arr)
buildMaxHeap(arr)
for i in range(len(arr)-1,0,-1):
swap(arr,0,i)
arrLen -=1
heapify(arr, 0)
return arr