堆排序的JS实现

JS实现堆排序

堆排序

堆的定义:
堆是满足下列性质的数列{R1,R2,R3,…,Rn}:
小顶堆:Ri <= R2i, Ri <= R2i
大顶堆:Ri >= R2i, Ri >= R2i

堆排序是在树形选择排序的基础上进一步进行优化

简单来说:就是假如将此序列看成一棵完全二叉树,要使这个无序列表变成堆,则小于等于n/2(最后一个非终端节点就是n/2)的某个节点i的左右子节点均大于此节点。

比如:49 38 65 97 76 13 27 49

  初始堆的树为: 
               49 
         38            65 
     97      76    13       27 
  49 

  构造堆后的树为 
                  13 
          38               27 
     49       76       65       49 
 97 

交换数据的顺序为:97<——>49, 13<—>65,38不用换,49<–>13,13<–>27

输出堆顶元素并调整建新堆的过程

输出堆顶最小值后,假设以最后一个值替代之,由于其左右子树的堆结构并没有被破坏只需要自上而下进行调整。比如把上图的13输出后以97替代,然后可以把97与27交换然后97又与49交换,此时最小值为根元素27,输出27后以又用最后一个值替换根元素以此类推,则最终得到有序序列。

效率:

时间复杂度:O(nlog2n)

空间复杂度: O(1)

稳定性:不稳定

js代码:

/* 排序思路:(降序)
 * 将堆根保存于尾部,并对剩余序列调用调整函数,调整完成后,再将最大跟保存于尾部-1(-1,-2,…,-i),
 * 再对剩余序列进行调整,反复进行该过程,直至排序完成。
 */

/* 将最大的元素调整到堆顶*/
function AdjustHeap(arr, pos, len){
    var swap = arr[pos];      //保存当前节点
    var child = pos * 2 + 1;  //定位到当前节点的左边的子节点
    while(child < len){       //递归遍历所有的子节点
        //判断当前节点是否有右节点,若右节点较大,就采用右节点和当前节点进行比较
        if(child + 1 < len && arr[child] < arr[child + 1]){
            child += 1;
        }
        //比较当前节点和最大的子节点,小于就交换,交换后将当前节点定位到子节点上
        if(arr[pos] < arr[child]){
            arr[pos] = arr[child];
            pos = child;
            child = pos * 2 + 1;
        }
        else{
            break;
        }
        arr[pos] = swap;
    }
}

/* 构建堆:
 * 满足:树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子结点的关键字。
 * 实现:从最后一个拥有子节点的节点开始,将该节点和其他节点进行比较,将最大的数交换给该节点,
 *      交换后再依次向前节点进行相同的交换处理,直到构建出大顶堆。
 */
function BuildHeap(arr){
  for(var i=arr.length/2; i>=0; i–){  //构建打顶堆
      AdjustHeap(arr, i, arr.length);
  }
}





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值