堆排序以及TopK大顶堆小顶堆求解方式(js版)

我理解的堆排序

  1. 堆排序是一种选择排序,时间复杂度o(nlogn),空间复杂度o(1)。
  2. 数据结构底层是数组,通过索引之间的关系可看二叉树,父结点总是大于或者小于孩子结点。这就是堆的结构。
  3. 刚初始完的堆是占据整个数组的。
  4. 开始排序后,数组分为两个部分!前面是堆,后面是已排序完的有序子数组。
  5. 排序时,堆顶元素和堆尾元素会交换,有序子数组长度+1,堆长度-1;此时,原堆尾元素占据了堆顶,可能会破坏了堆结构,所以,需要堆化,也就是堆顶元素要保持最大或者最小。
  6. 当堆只有一个元素,自动加入有序子数组;这时有序子数组占据整个数组。排序完成。

如何初始化堆

将普通数组初始为堆。

  1. 把数组arr看成一个二叉树,父结点与孩子结点的关系:root:i , leftChild:2i+1, rightChild:2i+2
  2. 找到索引最大的非叶子节点。数组长度length,假设length- 1= 2i + 1,则i=length/2 - 1。所以索引最大的非叶子结点是arr[i]。
  3. 堆化。也就是将[i,length - 1]的数组变成堆,然后i - 1,使堆长度+1,再堆化,这样反复操作,直到i == 0,让堆占满整个数组。
    //初始堆
    for (let i = (arr.length >> 1) - 1; i >= 0; i--) {
   
       //堆化
    }

堆化

  1. 用父结点与孩子结点比较,如果父结点比孩子结点大,则不调整位置(最大堆);否则,将孩子结点与父结点交换。
  2. 如果发生交换的话,再将孩子结点作为父结点,与它的孩子节点再作比较。直到叶子结点。
//compare=(a,b)=>a>b :最大堆;compare=(a,b)=>a<b :最小堆
/**
* i 堆顶索引
* end 堆尾索引+1
* compare 控制是最大堆还是最小堆
*/
function adjustHeap(arr, i, end, compare) {
   
    let tmp = arr[i];
    let parentIndex = i;
    let childIndex = 2 * i + 1;
    while (childIndex < end) {
   
        if (childIndex + 1 < end && !compare(arr[childIndex], arr[childIndex + 1])) {
   
            childIndex++;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值