1. 简介
一种数据结构,能取出数据的最值。他是基于比较结果进行的。
2. 堆的操作
在这里我们展现的是二叉堆,用一颗完全二叉树来实现。
堆满足一个任意一个顶点的子节点是不大于根节点的。
堆的最重要的操作是:
- 插入元素到堆中
- 将堆顶元素弹出堆
2.1 插入堆
由于是一颗完全二叉树,所以我们把插入的值放到最后的位置上来。
不断比较插入值与其父节点的大小,当满足堆序性时,插入到节点中,否则将父节点值下移。
插入过程
- 代码
#define MAXN 1000
struct heap {
heap():cnt(-1)
{}
void push(int v);
int pop();
bool empty() const
{ return cnt == -1;}
int cnt;
int node[MAXN];
};
void heap::push(int v) {
int cur = ++cnt;
int pa = (cur + 1) / 2 - 1;
int i;
for ( i = cnt; i != 0; i = pa) {
if ( v >= node[pa])
break;
node[i] = node[pa];
pa = (pa + 1) / 2 - 1;
}
node[i] = v;
}
2.2 删除堆顶
将删除前最后一个元素p
拿到堆顶,
不断比较左右子节点的值
取左右子节点最值child
的与p
值进行比较
若p优先则结束,将当前节点的值令为p的值。
否则将左右子节点优先值赋给当前节点
重复上面的过程。
删除过程
- 代码
int heap::pop()
{
if ( empty() )
return -1;
int most = node[0];
int v = node[cnt];
--cnt;
int child = 0;
int i;
for ( i = 0; i <= cnt; i = child) {
child = 2 * i + 1;
if (child + 1 <= cnt && node[child + 1] < node[child] )
++child;
if (child > cnt|| node[child] >= v)
break;
else
node[i] = node[child];
}
if (cnt != -1)
node[i] = v;
return most;
}
3. STL中的堆
大根堆
#include <queue>
using namespace std;
priority_queue<int, vector<int>, less<> > pq;
小根堆
#include <queue>
using namespace std;
priority_queue<int, vector<int>, greater<> > pq;