十大经典排序算法-堆排序算法详解

本文深入讲解了堆排序算法,包括其概念、原理、实现过程及特点。通过具体示例,展示了如何利用最大堆进行升序排序,以及算法的时间复杂度、空间复杂度和稳定性。堆排序是一种基于比较的排序算法,利用二叉堆的数据结构进行操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

十大经典排序算法

一、什么是堆排序

1.概念

堆排序(Heapsort)是利用二叉堆的概念来排序的选择排序算法,分为两种:

  • 升序排序:利用最大堆进行排序
  • 降序排序:利用最小堆进行排序
2.算法原理

给定一个最大堆如下图所示,以该最大堆进行演示堆排序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pA3T0B2E-1593593813254)(./堆1.png)]
首先,删除堆顶元素10(即最大的元素),并将最后的元素3补充到堆顶,删除的元素10,放置于原来最后的元素3的位置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xhj6pvKP-1593593813256)(./堆2.png)]
根据二叉堆的自我调整,第二大的元素9会成为二叉堆新的堆顶
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dqQ6As6S-1593593813258)(./堆3.png)]
删除元素9,元素8成为最大堆堆顶
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RGnf46zw-1593593813260)(./堆4.png)]
删除元素8,元素7成为最大堆堆顶
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0j119X1X-1593593813262)(./堆5.png)]
依次删除最大元素,直至所有元素全部删除
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QpnvGNu3-1593593813264)(./堆6.png)]
此时,被删除的元素组成了一个从小到大排序的序列
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4UVRJMQr-1593593813265)(./堆7.png)]

3.算法实现
// 下沉调整
// 最大堆
function downAdjust(arr, parentIndex, length) {
    // 缓存父节点的值,用于最后进行赋值,而不需要每一步进行交换
    let temp = arr[parentIndex];
    // 孩子节点下标,暂时定为左孩子节点下标
    let childIndex = 2 * parentIndex + 1;

    while (childIndex < length) {
        // 当存在右孩子节点,且右孩子节点的值小于左孩子节点的值,childIndex记录为右孩子节点的下标
        // childIndex实际记录的是最小的孩子节点的下标
        if (childIndex + 1 < length && arr[childIndex + 1] > arr[childIndex]) {
            childIndex++;
        }

        // 如果父节点的值比孩子节点的值都小,则调整结束
        if (temp >= arr[childIndex]) {
            break;
        }

        // 将最小的孩子节点的值赋值给父节点
        arr[parentIndex] = arr[childIndex];
        parentIndex = childIndex;
        childIndex = 2 * parentIndex + 1;
    }
    arr[parentIndex] = temp;
}

// 堆排序
function sort(arr) {
    // 把无序数组构建成二叉堆
    for (let i = parseInt(arr.length / 2) - 1; i >= 0; i--) {
        downAdjust(arr, i, arr.length);
    }
    console.log(arr);

    // 循环删除堆顶元素,移到集合尾部,调节堆产生新的堆顶
    for (let i = arr.length - 1; i > 0; i--) {
        // 最后一个元素与第一个元素交换
        [arr[0], arr[i]] = [arr[i], arr[0]];
        downAdjust(arr, 0, i);
    }
}

let arr = [10, 9, 8, 5, 6, 7, 1, 4, 2, 3];
sort(arr);
console.log(arr);

三、堆排序算法特点

1.时间复杂度

下沉调整的时间复杂度等同于堆的高度O(logn),构建二叉堆执行下沉调整次数是n/2,循环删除进行下沉调整次数是n-1,时间复杂度约为O(nlogn)

2.空间复杂度

堆排序算法排序过程中需要一个临时变量进行两两交换,所需要的额外空间为1,因此空间复杂度为O(1)

3.稳定性

堆排序算法在排序过程中,相同元素的前后顺序有可能发生改变,所以堆排序是一种不稳定排序算法


另外推荐一个开发者小工具网站,个人觉得里面的Json格式化功能很强大,报错很详细

https://tinyutil.cn/

还可以输入表达式进行内容选取,对于复杂json非常多层级的内容展现非常用用处
在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值