题目
解释
- 堆的本质是一个完全二叉树,最小数在顶部的叫做小根树,最大数在顶部的叫做大根树
- STL中priorityqueue的功能实质就是堆
- C++ STL详解(2)_ACfun-CSDN博客
- 手写堆的操作
- 插入一个数
- 求集合中最小值
- 删除最小值
- 删除任意一个元素
- 修改任意一个元素
//插入一个数
heap[++size]=x;down(size);
//求集合中的最小值
heap[1];
//删除最小值
heap[1]=heap[size];size--;down(1);
//删除任意一个元素
heap[k]=heap[size];size--;down(k);
//修改任意一个元素
heap[k]=x;down(k);
视频演示
代码段
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int n, m;
int h[N], cnt;
void down(int u)
{
int t = u;
if (u * 2 <= cnt&& h[u * 2] < h[t])t = u * 2;
//先判断当前根的左儿子,如果比其小,则用t保存这个左儿子的值
if (u * 2 + 1 <= cnt && h[u * 2 + 1] < h[t])t = u * 2 + 1;
//同理判断右儿子
//最终t保存的是这三个数里最小的一个
if (u != t)
{
swap(h[u], h[t]);
down(t);
//以当前t为父级,再进行一次比较
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> h[i];
cnt = n;
for (int i = n / 2; i; i--)down(i);
//给所有根进行排序,使其满足小根树的性质
//这里从n/2开始循环因为根据完全二叉树的性质
//从下标n/2+1开始,就全部是树的叶子了,然而我们只需要从父级开始遍历下沉
while (m--)
{
cout << h[1] << ' ';
h[1] = h[cnt--];
//用最大的一片叶子覆盖根,然后缩小cnt,重新排序
down(1);
}
puts("");
return 0;
}