堆、堆排序
2023-04-18 16:46:09 时间
堆的基本操作操作:
1、插入一个数:
数组末尾插入一个元素,并up()操作维护一下堆
heap[ ++ size] = x; up(size);
2、求集合当中的最小值:
小根堆的堆顶元素
heap[1]
3、删除最小值:
使用最后一个节点的值覆盖第一个节点的值,再把数组的下标--,再使用头节点down(1)运算维护一下堆。
heap[1] = heap[size]; size --; down(1);
4、删除任意一个元素(STL里面的堆无法进行的操作):
分情况判断,变大了或者变小了。
heap[k] = heap[size]; size -- ; down(k)或者up(k)
5、修改任意一个元素(STL里面的堆无法进行的操作)
heap[k] = x; down(k);或者 up(k);
堆的基本结构:
1、是一个平衡二叉树(即树除了最后一层节点可以不满以外,其它层的节点都是非空的,且最后一层节点是从左往右排列的)
2、小根堆:根节点的值小于左右子节点的值,所以根节点是最小值
堆的存储:
x的左二子是:2*x;x的右二子是:2*x+1;
注:下标从1开始比较好
堆的基本操作(时间复杂度为O(nlogn)):
down(x):x往下移动;当某个数变大的时候可以使用down操作
令根节点和根节点、左、右子节点中的最小值进行交换,重复此操作
up(x):x往上移动;当某个数变小的时候可以使用up操作
令数值较小节点和根节点、左、右子节点中的最小值进行交换,重复此操作
例题及模板代码:
堆排序(down()函数的使用)
题目内容
输入一个长度为n的整数数列,从小到大输出前m小的数。 输入格式
第一行包含整数n和m。
第二行包含n个整数,表示整数数列。
输出格式
共一行,包含m个整数,表示整数数列中前m小的数。
数据范围
1≤m≤n≤10^5 , 1≤数列中元素≤10^9
输入样例:
5 3
4 5 1 3 2
输出样例:1 2 3
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n,m;
int h[N],size;
void down(int u) {
int t = u;//使用t记录根节点的值
//让根节点分别和左右子节点进行对比
if(u*2<=size&&h[u*2]<h[t])
t=u*2;
if(u*2+1<=size&&h[u*2+1]<h[t])
t=u*2+1;
if(u!=t) {//说明根节点不是最小的值,需要进行交换
swap(h[u],h[t]);
down(t);
}
}
int main() {
scanf("%d%d",&n, &m);
for(int i=1; i<=n; i++)
scanf("%d",&h[i]);
size=n;
for(int i=n/2; i; i--)//从n/2开始排序能将时间复杂度降到O(n)
down(i);
while(m--) {
printf("%d ",h[1]);//取出最小值
h[1]=h[size];//删除根节点
size--;
down(1);
}
return 0;
}
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击