[C] 神奇的堆——最小堆,最大堆,堆排序

news/2024/11/17 20:31:58/

堆——神奇的优先队列

  • 堆是一种特殊的完全二叉树,所有父节点都比子节点药效,符合这样的二叉树称之为堆。
  • 反之,如果所有父节点都比子节点要大,这样的完全二叉树称为最大堆。

代码展示

  • 此处展示的是向上调整法建立最大堆。
#include<stdio.h>
int a[1000], n;void siftup(int i)
{int flag = 0;//用来标记是否还需要向上调整int t;if (i == 1)return;//如果是堆顶,就不用调整了。while (i != 1 && flag == 0){//判断是否比父节点大if (a[i] > a[i / 2]){t = a[i];a[i] = a[i / 2];a[i / 2] = t;}else{flag = 1; //表示不需要调整了}i = i / 2; //这句话很重要,更新编号为i为它父节点的编号,从而便于下一次继续向上调整}
}int main()
{int i;scanf("%d", &n);for (i = 1; i <= n; i++){scanf("%d", &a[i]);siftup(i);}for(i=1;i<=n;i++){printf("%d ",a[i]);}return 0;
}

运行结果:
在这里插入图片描述

  • 画出来就是这样,看,是不是变成最大堆了?

  • 这里数组里的编号很好理解,遵循从上到下从左到右的原则,依次编号。

  • 这样做的好处是,父结点的编号是子节点的1/2(根据向下取整原则,除以二可以正好得到父节点的编号。)

  • 这张图我画了好久才画出来~
    在这里插入图片描述

  • 如果想要建立最小堆呢?那只需要改一个符号

 if (a[i] < a[i / 2])

再运行就是最小堆了~
在这里插入图片描述


神奇的堆排序

  • 这里用到的是向下调整的方式,和上面不同,但思路类似。
  • 堆排序也是一种时间复杂度为O(nlogn)的绝佳的排序算法,配合最大堆的使用,原理是每次交换堆顶和队尾的值,每次交换后为了保持最大堆的特性,对堆顶值执行向下调整。
  • 这时你可能会问了,那队尾的最大值岂不是会破坏最大堆的特性?
  • 所以我们此时把总数n--,即:这个队的长度已经-1了,队以外的不是我们堆里的内容。(是已经排好的序列)
  • 每次都把最大值往最后丢,然后长度-1。(最大值是哪个?最大值是a[1]呀!)
  • 直到某一刻n=1时,表示这个堆已经被你丢完了,你的排序就完成了。
  • 具体代码如下:
#include<stdio.h>
int a[1000], n;//向下调整函数
void siftdown(int i)
{int flag = 0;//用来标记是否还需要调整int t;//当i结点有儿子while (i * 2 <= n && flag == 0){//先判断和左儿子的关系if (a[i] < a[i * 2])t = i * 2;elset = i;//有右儿子吗if (i * 2 + 1 <= n){//有右儿子,而且发现右儿子是父子中最大的if (a[t] < a[i * 2 + 1])t = i * 2 + 1;}//以上过程就是找父子一家人里最大的那个//如果发现最大结点编号不是自己的,说明子节点中有比父节点更大的,交换它们!int temp;if (t != i){temp = a[t];a[t] = a[i];a[i] = temp;i = t; //更新i为最大结点编号,便于接下来继续向下调整}elseflag = 1;//表示不需要调整了}
}void heapsort()
{int temp;while (n > 1){temp = a[1];a[1] = a[n];a[n] = temp;n--;siftdown(1);}
}void creat()
{int i;//从最后一个非叶子结点开始向上调整for (i = n / 2; i >= 1; i--){siftdown(i);}
}int main()
{int i, num;scanf("%d", &n);num = n;for (i = 1; i <= n; i++)scanf("%d", &a[i]);creat();//堆排序heapsort();for (i = 1; i <= num; i++){printf("%d ", a[i]);}return 0;
}

运行结果:
在这里插入图片描述

  • 神奇!你的排序到此就完成了!
  • 所以你更喜欢快排还是堆排序呢?(反正我是堆排序)

在此,《啊哈!算法》的前7章内容已经结束了,非常感谢纪磊老师,让我这么多年以来一直热爱着研究算法。


http://www.ppmy.cn/news/607496.html

相关文章

基于短语的统计机器翻(PBMT) 开源工具 :Moses

如何运行Moses 1. Moses的历史 Moses是Pharaoh的升级版本&#xff0c;增加了许多功能。它是一个基于短语的统计机器翻译系统&#xff0c;整个系统用C语言写成&#xff0c;从训练到解码完全开放源代码&#xff0c;可以运行在Linux平台和Windows平台。它有两大特点&#xff1a; 1…

自己做网站服务器需要买吗,自己做网站要买服务器

自己做网站要买服务器 内容精选换一换接入CDN做加速的域名必须满足如表1的要求。域名是否需要备案与域名提供商地域、网站服务器所处地域无关&#xff0c;与您加速域名的CDN加速服务范围有关。只要您的加速服务范围为中国大陆或全球&#xff0c;该域名就必须在工信部备案才能接…

C-V2X现场解析

C-V2X现场解析 什么是C-V2X&#xff1f; 5G时代万物将互联&#xff0c;人与人、人与物、物与物可以通过无线网络进行连接&#xff0c;C-V2X车联网技术也逐渐成为了主流。 C-V2X means Cellular Vehicle-to-Everything&#xff0c;是基于蜂窝网络的车用无线通信技术。V2X早期主…

[JavaScript] JavaScript数组挖掘,不只是讲数组哟(2)

课程来源&#xff1a;后盾人 上一篇的内容&#xff1a;[JavaScript] JavaScript数组挖掘&#xff0c;不只是讲数组哟 数组引用类型分析&#xff0c;多维数组&#xff0c;用Array.of为数组创建细节&#xff0c;类型检测与转换&#xff0c;在一个数组后面加一个新的数组&#xff…

pytorch记录:seq2seq例子看看这torch怎么玩的

https://blog.csdn.net/nockinonheavensdoor/article/details/82320580 先看看简单例子&#xff1a; import torch import torch.autograd as autograd import torch.nn as nn import torch.nn.functional as F import torch.optim as optim torch.manual_seed(1) 1234567用tor…

ajax发送动态字符传,如何发送ajax请求文件与其他字符串的变量?

我想创建ajax调用并发送数据与文件和其他变量&#xff0c;我也使用django&#xff0c;如果它的帮助。如何发送ajax请求文件与其他字符串的变量&#xff1f;我尝试&#xff1a;js文件&#xff1a;$("#save-new-request-testBtn").click(function(){var project $(#pr…

云原生(三十四) | Kubernetes篇之平台存储系统实战

文章目录 Kubernetes平台存储系统实战 一、块存储(RDB) 1、配置 二、STS案例实战 三、文件存储(CephFS) 1、配置 2、测试 四、pvc扩容 动态卷扩容 Kubernetes平台存储系统实战 一、块存储(RDB) RDB&#xff1a; RADOS Block Devices RADOS&#xff1a; Reliable, A…

地平线 征程® 3

地平线 征程 3 新一代高性能车规级 AI 芯片 征程3 是地平线基于自研的BPU2.0 架构&#xff0c;针对高级别辅助驾驶场景推出的新一代高效能车规级 AI 芯片&#xff0c;已通过 AEC-Q100 认证。征程3 不仅支持基于深度学习的图像检测、分类、像素级分割等功能&#xff1b;也支持对…