堆排序 Heap Sort
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法。堆排序是选择排序的一种(树形选择排序)。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,堆是一种完全二叉树。最大(小)的值一定在堆顶。
n个关键字序列K1,K2,…,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质):
K(i)<=K(2i)且K(i)<=K(2i+1)(1≤i≤n/2),当然,这是小根堆,大根堆则换成>=号。
K(i)相当于二叉树的非叶子结点,K(2i)则是左子节点,K(2i+1)是右子节点
若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:
树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。
注意:
- 堆中任一子树亦是堆。
- 以上讨论的堆实际上是二叉堆(Binary Heap),类似地可定义k叉堆
- 树的高度从0开始算,树中的节点序号从1开始算。
- 同一组数按满足堆序性质去排列,将有不止一种结果。
算法实现总结:(min堆)
- insert():
空穴上滤(percolate up),元素下移
平均时间复杂度: O(1);
最坏时间复杂度: O(logN); 即高度 - deleteMin():
空穴下滤(percolate down),元素上移
平均时间复杂度: O(logN); 即高度
最坏时间复杂度: O(logN); 即高度 - buildHeap():
用N次insert()来理解,而不是用调整(树中所有节点的高度和)来理解
平均时间复杂度: O(N); N次insert()操作.
然而一般的实现是将N个关键字以任意顺序放入树中,然后从N/2处开始对节点进行下滤,大数下滤(树的调整)
此处的下滤是节点的下滤,而不是空穴的下滤
for(i = N/2; i > 0; --i){
percolateDown(i);
}
树中所有节点的高度和可以近似理解为O(N)
4. 节点下滤,是一个递归的过程。
堆排序是就地排序,辅助空间为O(1).
堆排序是不稳定的排序方法.