本文是对二叉堆以及STL中priority_queue的简单介绍。
二叉堆的基本概念
二叉堆是一种树状的堆,准确的说是一个完全二叉树构成的堆,并且在树根处的值是唯一的极值,其中在二叉堆中可以进行的数据操作是:
1.寻找并输出最大(最小)值
2.弹出最大(最小)值
3.插入新数值
在STL中优先队列的模型是建立在二叉堆的基础上的,所以通常使用优先队列来表示二叉堆。
二叉堆的模型
二叉堆通常会用数组直接模拟。
int heap[1<<N + 10]; //这里运用建树的方式直接建堆,同时令heap[1]为堆顶
int size = 1; //size用来标记最后元素的位置
二叉堆的功能函数
二叉堆的输出
根据二叉堆的性质,堆顶(树根)处就时堆的极值。
代码如下:
int top(){
return heap[1];
}
二叉堆的插入
二叉堆的插入首先需要满足完全二叉树,因而插入的位置必定是最小的叶子结点。
插入过程有顺序关系,我们不妨假设:
1.该堆是小顶堆。
2.元素3>元素1>新元素
由于元素3>新元素 因而交换其位置。
同上交换元素1与新元素位置。
这样就构成了新的堆。
代码实现如下:
void insert(int newelement){
a[size] = newelement;
int pos = size++;
while(a[pos] >= a[pos>>1] ){
swap(a[pos],a[pos>>1]);
pos>>=1;
if(pos == 1) break;
}
}
二叉堆的删除
二叉堆的删除也需要将堆中极值从堆顶转移到叶子结点,然后删除叶子结点。
不妨假设:待删除元素>元素5>元素2>元素1
经过比较待删除元素的左右子结点,将元素1与待删除元素交换。
同理交换箭头所指两元素。由于交换后待删除元素已经到达叶子结点,于是直接删除。
这样新的二叉堆就完成了。
代码如下:
void pop(){
int pos = 1;
while(pos <= size){
if(heap[pos<<1] > heap[pos<<1+1]){
swap(heap[pos],heap[pos<<1+1]);
pos = pos<<1+1;
}
else{
swap(heap[pos<<1],heap[pos]);
pos = pos<<1;
}
}
}
STL heap 与 priority_queue
C++ STL库中包含建堆用的heap库与二叉堆的priority_queue。
对于堆需要以下头文件
#include<heap>
对于优先队列需要以下头文件
#include<queue>
这里不赘述堆的操作,因为二叉堆只是堆中一部分,而优先队列与二叉堆切合度较高,所以只介绍优先队列的操作。
优先队列的构造
priority_queue<int,vector<int>,less<int> > pq1; //大顶堆
priority_queue<int,vector<int>,greater<int> > pq2; //小顶堆
若使用结构体需要重载 < 运算符。
优先队列部分函数
功能 | 函数名 | 返回值类型 |
---|---|---|
判断队列是否为空 | empty() | bool |
队列内元素数量 | size() | int |
元素进队 | push(int n) | void |
队首元素出队 | pop() | void |
显示队顶元素 | top() | template T |