js堆排序及其topk问题

本文深入探讨了堆排序算法,包括小根堆的向下调整函数实现,以及如何利用堆排序解决TOPK问题。堆排序是一种高效排序方法,适用于寻找数组中的前K大元素。通过建立小根堆并不断调整,可以确保堆顶元素始终为最小,从而在O(n log n)的时间复杂度内完成排序。同时,堆排序也被应用于实际场景中的TOPK问题,能够快速找到数组中最大的K个元素。
摘要由CSDN通过智能技术生成

堆排序

堆其实就是一棵完全二叉树

小根堆向下调整函数如下:

function sift2(arr, low, high) {
//low表示当前需要调整的子树的根节点
//i表示的是当前的空位
    let i = low;
    //j表示当前子树的左孩子
    let j = 2 * i + 1;
    //缓存当前子树的根节点
    let tmp = arr[low];
    //如果左孩子小于或等于树的大小
    while (j <= high) {
    	//判断当前节点的右孩子存不存在并且和左孩子比较大小
        if (j + 1 <= high && arr[j + 1] < arr[j]) {
            j = j + 1;
        }
        // 如果当前节点大于较小的那个孩子 就让较小的孩子到空位上去 然后空位下移
        if (tmp > arr[j]) {
            arr[i] = arr[j]
            i = j;
            j = 2 * i + 1;
        } else {
            break
        }
    }
    //将刚开始要调整的那个节点放到空位上去
    arr[i] = tmp;
}


function heapSort2(arr) {
    let n = arr.length;
    
    for (let i = (n - 2) >> 1; i >= 0; i--) {
        sift2(arr, i, n - 1)
    }
    //挨个出数
    for (let i = n - 1; i >= 0; i--) {
        [arr[0], arr[i]] = [arr[i], arr[0]]
        sift2(arr, 0, i - 1)
    }
}

使用情况,TOPK问题

// TopK问题找前K大的数需要创建小根堆
function topk(arr, k) {
    // 取前K个数创建小根堆
    let heap = arr.slice(0, k)
    for (let i = (k - 2) >> 1; i >= 0; i--) {
        sift2(heap, i, k - 1)
    }
    // 创建小根堆
    // 用后面的数和堆顶的数比较如果后面的数大那么就替换掉堆顶的元素并且向下调整一次使得堆顶元素最小
    for (let j = k; j < arr.length; j++) {
        if (arr[j] > heap[0]) {
            heap[0] = arr[j];
            sift2(heap, 0, k - 1)
        }
    }
    // 至此前K大的数已经就绪就在heap数组中,但是不是按照顺序排列的

    // 挨个出数来保证前K大的数挨个排列  
    for (let i = k - 1; i >= 0; i--) {
        [heap[0], heap[i]] = [heap[i], heap[0]]
        sift2(heap, 0, i - 1)
    }
    return heap
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值