堆的基本操作操作:
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
#include
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]