排序算法之堆排序

发布于 2022-06-10 14:05:34 字数 2604 浏览 1021 评论 0

堆排序(不稳定,相同的两个数字会被交换)(适合大数据量的排序)

堆和数组的相互关系

对于给定的某个结点的下标 i,可以很容易的计算出这个结点的父结点、孩子结点的下标:(注意:数组都是 Zero-Based,以零开始)

Parent(i) = floor((i-1)/2),i 的父节点下标
Left(i) = 2i + 1,i 的左子节点下标
Right(i) = 2(i + 1),i 的右子节点下标

最大堆调整(MAX‐HEAPIFY)的作用是保持最大堆的性质,是创建最大堆的核心子程序,作用过程如图所示:

但是一次调整后,堆仍然违反堆性质,所以需要递归的测试,使得整个堆都满足堆性质。

步骤:

  • 最大堆调整函数
  • 创建最大堆数组函数
  • 堆排序(一步步将堆缩小)
function heapSort(arr) {
    function swap(arr, i, j) {
        let temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp
    }

    //最大堆调整函数
    function maxHeapify(arr, index, heapSize) {
        let iMax,
             iLeft,
             iRight
             
        //这里可以使用递归。递归调用需要压栈/清栈,和迭代相比,性能上有略微的劣势   
        while(true) {
            iMax = index   // index为当前结点
            iLeft = 2 * iMax + 1
            iRight = 2 * (iMax + 1)
            
            if(iLeft < heapSize && arr[iLeft] > arr[index]) {//index
                iMax = iLeft
            }
            
            if(iRight < heapSize && arr[iRight] > arr[iMax]) {//iMax
                iMax = iRight
            }
            
            if(iMax != index) {
                swap(arr, iMax, index)
                index = iMax
            }else {  //记得终止,不然会无限循环,导致内存溢出
                break
            }
        }
    }
    
    //从最后一个非叶子节点开始,自下而上进行最大堆调整(调用最大堆调整函数)
    function buildMaxHeap(arr) {
        let iParent = Math.floor((arr.length - 1) / 2)
        
        for(let i = iParent; i>=0; i--) {  // i>=0
            maxHeapify(arr, i, arr.length)
        }
    }
    
    //对于调整好的最大堆数组,将堆顶元素与堆底元素交换,然后将堆底最后一位元素砍掉(隔离),产生的新的堆会一点点缩小,
    //此时新的堆只需要对下标为0的元素进行最大堆调整即可。调整完了之后,重复上述步骤,直到堆数组只剩下一位根元素,就完成了对数组从小到大的排序。
    function sort(arr) {
        buildMaxHeap(arr)
        
        let len = arr.length
        for(let i = len - 1; i>0; i--) {
            swap(arr, 0, i)
            maxHeapify(arr, 0, i) // i
        }
        
        return arr
    }
    
    return sort(arr)
}

算法分析:

最佳情况:T(n) = O(nlogn)
最差情况:T(n) = O(nlogn)
平均情况:T(n) = O(nlogn)

Reference

堆排序 (Heap Sort)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

烙印

文章 0 评论 0

singlesman

文章 0 评论 0

独孤求败

文章 0 评论 0

晨钟暮鼓

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文