0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

难度系数最高之堆排序简介

学益得智能硬件 来源:学益得智能硬件 2023-02-25 09:29 次阅读

今天来看一个比较复杂的排序,堆排序,先搞清楚原理,再写代码。

堆排序使用数据结构中的堆来完成,那么问题来了,什么是堆?

有两种,大顶堆和小顶堆,所谓大顶堆,就是任意一个双亲节点都比孩子节点大,比如图上这样的,小顶堆则反过来。

496617d8-b43f-11ed-bfe3-dac502259ad0.png

所以对于大顶堆来说,根节点一定是最大的。

比如有这样一个数组,先把它画成一颗二叉树的形式,接下来就是构建大顶堆,这个部分也是整个堆排序中最耗时的部分。

4b989846-b43f-11ed-bfe3-dac502259ad0.png

从0这个节点开始,因为节点0是最后一个有孩子的节点。

0比2小,交换一下位置。

4be1d10a-b43f-11ed-bfe3-dac502259ad0.png

再轮到4,8和9比较,显然是9大,把9和4交换一下位置。

4cc4f00c-b43f-11ed-bfe3-dac502259ad0.png

最后轮到3,9比2大,9和3需要交换一下位置。

4de944a6-b43f-11ed-bfe3-dac502259ad0.png

注意,因为这个节点发生了变化,所以3 8 4不再满足条件,还得继续调整。8比4大,8和3交换一下位置。

4ec34c46-b43f-11ed-bfe3-dac502259ad0.png

这个过程就是构建大顶堆。

于是,我们得到了最大的数字9,把它和最后一个数字做交换,然后断开,意思就是后面的操作跟9没有关系了。

4ee1fd1c-b43f-11ed-bfe3-dac502259ad0.png

接下来就是调整大顶堆,不需要再像刚才那样构建,因为这颗二叉树也只有根节点被修改了。

0和8交换,4和0交换,又得到了第二大的数字8。

4fe981da-b43f-11ed-bfe3-dac502259ad0.png

不断的重复,最后就是一个有序的序列。

写代码之前,还得明确一个问题,虽然我们一直在操作二叉树,但是写代码的时候并不需要真的去创建一颗二叉树,我们只是在操作数组的下标,比如下标为n的节点作为根几点,那么他的左孩子就是 2n+1,右孩子就是2n+2。

#include 


void adjust_heap_sort(int *a, int root, int last)
{
    int child;


    while (1)
    {
        child = 2 * root + 1;
        if (child > last)
            break;


        if (child + 1 <= last && a[child] < a[child + 1])
        {
            child++;
        }


        if (a[child] > a[root])
        {
            int num = a[root];
            a[root] = a[child];
            a[child] = num;
        }


        root = child;
    }
}


void heap_sort(int *a, int size)
{
    //构建大顶堆
    for (int i = size / 2 - 1; i >= 0; i--)
    {
        adjust_heap_sort(a, i, size - 1);
    }


    //调整大顶堆
    for (int i = size - 1; i > 0; i--)
    {
        int num = a[0];
        a[0] = a[i];
        a[i] = num;


        adjust_heap_sort(a, 0, i - 1);
    }
}


int main()
{
    int array[] = {3, 4, 0, 8, 9, 2};


    heap_sort(array, 6);


    for (int i = 0; i < sizeof(array) / sizeof(array[0]); i++)
    {
        printf("%d ", array[i]);
    }
    printf("
");


    return 0;
}
代码确实不太容易理解,不过在这些排序算法中,越是不容易理解的,效率也就越高,还是用它和冒泡做个对比,10000个数据,差距还是很大的。
root@Turbo:test# time ./heap_sort 


real  0m0.005s
user  0m0.004s
sys  0m0.000s
root@Turbo:test# time ./bubble_sort 


real  0m0.606s
user  0m0.554s
sys  0m0.000s
root@Turbo:test#




审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 交换机
    +关注

    关注

    20

    文章

    2612

    浏览量

    99152
  • 二叉树
    +关注

    关注

    0

    文章

    74

    浏览量

    12304

原文标题:难度系数最高-堆排序

文章出处:【微信号:学益得智能硬件,微信公众号:学益得智能硬件】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    FPGA排序-冒泡排序介绍

    排序算法是图像处理中经常使用一种算法,常见的排序算法有插入排序、希尔排序、选择排序、冒泡排序、归
    发表于 07-17 10:12 1053次阅读
    FPGA<b class='flag-5'>排序</b>-冒泡<b class='flag-5'>排序</b>介绍

    排序算法选择排序

    选择排序: (Selection sort)是一种简单直观的排序算法,也是一种不稳定的排序方法。 选择排序的原理: 一组无序待排数组,做升序排序
    的头像 发表于 09-25 16:30 1626次阅读
    <b class='flag-5'>排序</b>算法<b class='flag-5'>之</b>选择<b class='flag-5'>排序</b>

    十种常用排序法详解总结和比较选择

    (nlgn)的排序方法:快速排序堆排序或归并排序。  快速排序是目前基于比较的内部排序中被认为
    发表于 10-26 15:11

    常用排序法之一 ——冒泡排序法和选择排序

    语言中,常用的算法有:冒泡排序、快速排序、插入排序、选择排序、希尔排序堆排序以及归并
    发表于 11-01 12:25

    C语言教程之几种排序算法

    数据结构的排序算法有很多种。 其中, 快速排序 、希尔排序堆排序、直接选择排序不是稳定的排序
    发表于 11-16 10:23 1743次阅读

    c语言排序算法选择排序

    应广大"鸟友"强烈要求,小编将会推出《排序系列》,给大家讲讲排序那些事。        那么今天首先给大家讲解最符合人类思维逻辑的超简单排序法☞《选择排序法》。        顾名
    发表于 11-16 10:25 3424次阅读
    c语言<b class='flag-5'>排序</b>算法<b class='flag-5'>之</b>选择<b class='flag-5'>排序</b>法

    基于C语言二分查找排序源代码

    本文档内容介绍了C语言归并、选择、直接插入、希尔、冒泡、快速、堆排序与顺序、二分查找排序源代码,分享给大家供大家参考。
    发表于 01-04 11:24 1次下载

    常用排序算法分析

    一种是比较排序,时间复杂度O(nlogn) ~ O(n^2),主要有:冒泡排序,选择排序,插入排序,归并排序
    的头像 发表于 07-13 16:13 2131次阅读

    区块链挖矿难度系数设计的java实现

    先给大家介绍区块链挖矿难度系数的概念。区块链的难度系数:是设计区块链挖矿难易的关键因子,难度系数
    的头像 发表于 10-18 09:24 4268次阅读

    几种c语言程序的排序包括应用程序等资料免费下载

    本文档的主要内容详细介绍的是几种c语言程序的排序包括应用程序好资料免费下载包括了:堆排序,改进冒泡排序,归并排序,简单插入排序,简单选择
    发表于 09-29 08:00 6次下载
    几种c语言程序的<b class='flag-5'>排序</b>包括应用程序等资料免费下载

    你知道如何实现区块链难度系数

    区块链的难度系数:是设计区块链挖矿难易的关键因子,难度系数越低,挖矿越容易。难度系数越高,相应越
    发表于 12-18 10:42 2645次阅读

    C语言排序堆排序的技巧

    调整,使得子节点永远小于父节点 创建最大堆(Build Max Heap):将堆中的所有数据重新排序 堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算。 C代码实现 代码看起来比较抽象,将代码运行时数据交换的过程打印出来,然后
    的头像 发表于 07-29 15:29 1220次阅读
    C语言<b class='flag-5'>排序</b>中<b class='flag-5'>堆排序</b>的技巧

    解析数据结构的常用七大排序算法

    为了让大家掌握多种排序方法的基本思想,本篇文章带着大家对数据结构的常用七大算法进行分析:包括直接插入排序、希尔排序、冒泡排序、快速排序、简单
    的头像 发表于 03-16 08:22 1640次阅读

    2分钟看懂快速排序的算法

    之前有同学提出想要复习一下排序算法,那我们今天就挑一个难度中等的,快速排序
    的头像 发表于 02-25 09:32 764次阅读

    随机数字排序教程

    本次实验我们利用对随机数字进行排序来给大家介绍排序算法的实现,常见的快速排序、归并排序堆排序、冒泡排序
    的头像 发表于 03-24 14:55 963次阅读
    随机数字<b class='flag-5'>排序</b>教程