堆排序

Posted hff-syt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆排序相关的知识,希望对你有一定的参考价值。

1.堆排序

  • 堆是一个完全二叉树。
  • 完全二叉树: 二叉树除开最后一层,其他层结点数都达到最大,最后一层的所有结点都集中在左边(左边结点排列满的情况下,右边才能缺失结点)。
  • 大顶堆:根结点为最大值,每个结点的值大于或等于其孩子结点的值。
  • 小顶堆:根结点为最小值,每个结点的值小于或等于其孩子结点的值。

对二叉树做升序排序,总共分为三步:

1.将初始二叉树转化为大顶堆(heapify)(实质是从第一个非叶子结点开始,从下至上,从右至左,对每一个非叶子结点做shiftDown操作),此时根结点为最大值,将其与最后一个结点交换。

2.除开最后一个结点,将其余节点组成的新堆转化为大顶堆(实质上是对根节点做shiftDown操作),此时根结点为次最大值,将其与最后一个结点交换。

3.重复步骤2,直到堆中元素个数为1(或其对应数组的长度为1),排序完成。


var?len;
????function?buildMaxHeap(arr)?{???//建堆
????????len?=?arr.length;
????????//?[n/2-1]表示的是最后一个有子节点?(本来是n/2(堆从1数起),但是这里arr索引是从0开始,所以-1)
????????for?(var?i?=?Math.floor(len/2)-1;?i>=0;?i--)?{
????????????maxHeapify(arr,?i);
????????}
????????//对每一个节点(非叶节点),做堆调整
????}
????function?maxHeapify(arr,?i)?{?????//堆调整
????????var?left?=?2*i+1,
????????????right?=?2*i+2,
????????????largest?=?i;???//i为该子树的根节点
?
????????if?(left?<?len?&&?arr[left]?>?arr[largest])?{
????????????largest?=?left;
????????}
?
????????if?(right?<?len?&&?arr[right]?>?arr[largest])?{
????????????largest?=?right;
????????}
?
????????if?(largest?!=?i)?{??//即上面的if中有一个生效了
????????????swap(arr,?i,?largest);??//交换最大的为父节点
????????????maxHeapify(arr,?largest);??//交换后,原值arr[i](往下降了)(索引保存为largest),
????????????//作为根时,子节点可能比它大,因此要继续调整
????????}
????}
????function?swap(arr,?i,?j)?{
????????var?temp?=?arr[i];
????????arr[i]?=?arr[j];
????????arr[j]?=?temp;
????}
????function?heapSort(arr)?{
????????buildMaxHeap(arr);
????????for?(var?i?=?arr.length-1;?i?>?0;?i--)?{
????????????swap(arr,?0,?i);
????????????len--;
????????????maxHeapify(arr,?0);
????????}
????????return?arr;
????}

以上是关于堆排序的主要内容,如果未能解决你的问题,请参考以下文章

选择排序(简单选择排序堆排序的算法思想及代码实现)

排序--08---堆排序

python代码实现堆排序

算法-java代码实现堆排序

一文带你了解堆排序

堆排序