码迷,mamicode.com
首页 > 编程语言 > 详细

堆排序

时间:2020-03-10 11:51:47      阅读:80      评论:0      收藏:0      [点我收藏+]

标签:func   一个   所有结点   math   down   cti   heapsort   最大值   最大   

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;
????}

堆排序

标签:func   一个   所有结点   math   down   cti   heapsort   最大值   最大   

原文地址:https://www.cnblogs.com/hff-syt/p/12454529.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!