堆知识梳理

堆知识梳理

堆的特点

1.堆是一棵完全二叉树,所以除了根节点和最后一个左子结点可以没有兄弟结点,其它结点都必须有
2.根节点中的数要么是堆中的最大数(大根堆),要么是堆中的最小数(小根堆)
大根堆:

小根堆:

堆的存储

我们在前面提到过,堆是一棵完全二叉树,所以它是用数组存储的,根节点存在下标为1的位置,此后每个结点(在n处)的左子节点存在2n处,右子节点存在2n+1处

下标 1 2 3 4 5 6 7
数字 95 38 45 11 20 33 27

手写堆

虽然接下来的内容有点复杂,但还是希望大家自己手打一边,手打堆可以发掘出堆的更多用法

加入数据

首先,我们有一个数据52,然后,我们有一个伟大的决定,将它加入大根堆(小根堆)

下标 1 2 3 4 5 6
数字 84 55 32 26 42 12

然后,我们将新数据放在树(数组)的末尾

下标 1 2 3 4 5 6 7
数字 84 55 32 26 42 12 52

最后,我们将它与它的父亲比较,如果它大于(小于)它的父亲,那么交换,重复这一系列动作,直到它的父亲大于(小于)它为止

下标 1 2 3 4 5 6 7
数字 84 55 52 26 42 12 32

代码

void put(int n){//大根堆代码,n为加入的值
	int now,nex;//now为现在的下标,nex为heap[now]的父亲
	heap[++heap_size] = n;//把n加到数组的最后
	now = heap_size;
	while(now > 1) {
		nex = now / 2;
		if(heap[now] <= heap[nex]) break;
		swap(heap[now],heap[nex]);//交换heap[now]和heap[nex]
		now = nex;
	}
}
void put(int n){//小根堆代码,n为加入的值
	int now,nex;//now为现在的下标,nex为heap[now]的父亲0
	heap[++heap_size] = n;//把n加到数组的最后
	now = heap_size;
	while(now > 1) {
		nex = now / 2;
		if(heap[now] >= heap[nex]) break;
		swap(heap[now],heap[nex]);//交换heap[now]和heap[nex]
		now = nex;
	}
}

弹出数据

堆只支持对堆顶进行弹出,所以弹出后我们还需要继续维护堆
弹出后,我们的堆会变成两个堆,依旧有序

下标 1 2 3 4 5 6 7
数字 55 52 26 42 12 32

我们将这两个堆的堆顶中大的(小的)那个拿来做堆顶

下标 1 2 3 4 5 6 7
数字 55 52 26 42 12 32

我们可以发现,被那去做堆顶的那个数据的所属堆的堆顶不见了(如上面表格下标为2的空位)
那么我们重复做上面的步骤直到移到叶子结点

下标 1 2 3 4 5 6
数字 55 52 42 12 32 26

代码

int pop(){//大根堆代码
	int now = 1,nex,res = heap[1];//now为现在的下标,nex为heap[now]的父亲,res为堆顶
	heap[1] = heap[heap_size --];
	while(now * 2 <= heap_size){
		nex = now * 2;
		if(nex < heap_size && heap[nex + 1] < heap[nex]) nex ++;
		if(heap[now] >= heap[nex]) break;
		swap(heap[now],heap[nex]);
		now = nex; 
	}
	return res;
}
int pop(){//小根堆代码
	int now = 1,nex,res = heap[1];//now为现在的下标,nex为heap[now]的父亲,res为堆顶
	heap[1] = heap[heap_size --];
	while(now * 2 <= heap_size){
		nex = now * 2;
		if(nex < heap_size && heap[nex + 1] < heap[nex]) nex ++;
		if(heap[now] <= heap[nex]) break;
		swap(heap[now],heap[nex]);
		now = nex; 
	}
	return res;
}

STL

STL是c++自带的,操作简便,但过于死板,堆是由优先队列实现的

定义

优先队列的排序顺序不是以到达的先后顺序排序,而是按照其优先级排序,与堆相同,所以用其来实现堆
优先队列属于

#include<queue>

定义

priority_queue <int,vector<int>,greater<int> >q1;//小根堆
priority_queue <int,vector<int>,less<int> >q2;//大根堆
priority_queue <int>q3;//大根堆
注意:q1,q2定义时<int> >q1的空格

拓展:vector为STL中的动态数组

基本操作

q.empty();//如果队列为空,返回1,否则返回0 
q.size();//返回队列中元素的个数 
q.pop();//删除队首元素,无返回值 
q.top();//返回队首元素 
q.push(x);//让x入队 
q.back();//返回队尾元素 
q.emplace();//造一个数据插入队中 (c++11新特性) 

对顶堆

是由一个大根堆和一个小根堆组成的,用于求第k大

思想

我们建一个大根堆,一个小根堆
其中一个限制它大小为k,如果一个数据大于(小于)这个堆的顶,那么存入,否则存入另一个堆
这样最后限制大小的堆的堆顶就是最终答案
我们来看一道题 The kth great number(对顶堆)

完结撒花

欢迎大家留言
小编蒟蒻一个,有什么问题请大佬不惜赐教Orz

posted @   骆美辰  阅读(49)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
  1. 1 淋雨一直走 张韶涵
  2. 2 一期一会《未闻花名》(Cover 茅野愛衣,戸松遥,早見沙織) 周深
  3. 3 起风了 吴青峰
  4. 4 极恶都市 夏日入侵企划
起风了 - 吴青峰
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 米果

作曲 : 高橋優

编曲 : 刘胡轶/貢多杰

制作人 : 刘胡轶/吴青峰

配唱制作人 : 刘胡轶

乐器监制 : 刘胡轶

吉他 : 胡晨

贝斯 : 甯子达

弦乐录音棚 : 中国剧院录音棚

录音工程师 : 倪涵文/李游/李杨/邢铜/韩宽/李巍

录音监制 : 倪涵文/李游

混音&母带工作室 : OKmastering studio

混音&母带工程师 : 全相彦

制作协力 : 刘西洋

制作发行 : 智慧大狗 × 天才联盟

出品人 : 张葛

监制 : 崔恕/王明宇

弦乐监制 : 李朋

弦乐 : 国际首席爱乐乐团

鼓(打击乐):祁大为

和音编写&演唱:鱼椒盐

人声&吉他&鼓(打击乐)录音棚:55Tec studio

我曾将青春翻涌成她

我曾将青春翻涌成她

也曾指尖弹出盛夏

心之所动 且就随缘去吧

这一路上走走停停

这一路上走走停停

顺着少年漂流的痕迹

迈出车站的前一刻

竟有些犹豫

不禁笑这近乡情怯

不禁笑这近乡情怯

仍无可避免

而长野的天

依旧那么暖

风吹起了从前

从前初识这世间

从前初识这世间

万般流连

看着天边似在眼前

也甘愿赴汤蹈火去走它一遍

如今走过这世间

如今走过这世间

万般流连

翻过岁月不同侧脸

措不及防闯入你的笑颜

我曾难自拔于世界之大

我曾难自拔于世界之大

也沉溺于其中梦话

不得真假 不做挣扎 不惧笑话

我曾将青春翻涌成她

我曾将青春翻涌成她

也曾指尖弹出盛夏

心之所动 且就随缘去吧

逆着光行走 任风吹雨打

短短的路走走停停

短短的路走走停停

也有了几分的距离

不知抚摸的是故事 还是段心情

也许期待的不过是 与时间为敌

再次看到你

微凉晨光里

笑得很甜蜜

从前初识这世间

从前初识这世间

万般流连

看着天边似在眼前

也甘愿赴汤蹈火去走它一遍

如今走过这世间

如今走过这世间

万般流连

翻过岁月不同侧脸

措不及防闯入你的笑颜

我曾难自拔于世界之大

我曾难自拔于世界之大

也沉溺于其中梦话

不得真假 不做挣扎 不惧笑话

我曾将青春翻涌成她

我曾将青春翻涌成她

也曾指尖弹出盛夏

心之所动 且就随缘去吧

晚风吹起你鬓间的白发

晚风吹起你鬓间的白发

抚平回忆留下的疤

你的眼中 明暗交杂 一笑生花

我仍感叹于世界之大

我仍感叹于世界之大

也沉醉于儿时情话

不剩真假 不做挣扎 无谓笑话

我终将青春还给了她

连同指尖弹出的盛夏

心之所动 就随风去了

以爱之名 你还愿意吗

lock: { enable: true, background: 'https://img1.baidu.com/it/u=2788089125,168843488&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1690563600&t=35fa4326e773b3fbf83562ad746b7cd2',//锁屏背景 strings: [ 'Every win named never give up 每一份胜利都叫不放弃',//签名 ], },
点击右上角即可分享
微信分享提示