堆排序 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]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:

树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。

注意:

  1. 堆中任一子树亦是堆。
  2. 以上讨论的堆实际上是二叉堆(Binary Heap),类似地可定义k叉堆
  3. 树的高度从0开始算,树中的节点序号从1开始算。
  4. 同一组数按满足堆序性质去排列,将有不止一种结果。

算法实现总结:(min堆)

  1. insert():
    空穴上滤(percolate up),元素下移
    平均时间复杂度: O(1);
    最坏时间复杂度: O(logN); 即高度
  2. deleteMin():
    空穴下滤(percolate down),元素上移
    平均时间复杂度: O(logN); 即高度
    最坏时间复杂度: O(logN); 即高度
  3. buildHeap():
    用N次insert()来理解,而不是用调整(树中所有节点的高度和)来理解
    平均时间复杂度: O(N); N次insert()操作.
    然而一般的实现是将N个关键字以任意顺序放入树中,然后从N/2处开始对节点进行下滤,大数下滤(树的调整)
    此处的下滤是节点的下滤,而不是空穴的下滤
for(i = N/2; i > 0; --i){
    percolateDown(i);
}

树中所有节点的高度和可以近似理解为O(N)
4. 节点下滤,是一个递归的过程。

      堆排序是就地排序,辅助空间为O(1).
      堆排序是不稳定的排序方法.

References:

堆排序

原文地址:https://www.cnblogs.com/lxw0109/p/heap-sort.html