一、什么是优先队列
优先队列不是按照普通对象先进先出原FIFO则进行数据操作,其中的元素有优先级属性,优先级高的元素先出队。本文提到的优先队列,是基于最小堆原理实现。
二、什么是最小堆
- 最小堆是一个完全二叉树,所谓的完全二叉树是一种没有空节点的二叉树。
- 最小堆的完全二叉树有一个特性是根节点必定是最小节点,子女节点一定大于其父节点。还有一个特性是叶子节点数量=全部非叶子节点数量+1
- 在优先队列中,基于数组保存了完全二叉树。所以在已知任意一个节点在数组中的位置,就可以通过一个公式推算出其左子树和右子树的下标。已知节点下标是i,那么他的左子树是2*i+1,右子树是2*i+2。
三、实现
包括以下方法:
- Push() 向队列添加一个元素
- Pop() 删除队首元素
- size() 返回当前队列元素个数
- Front() 返回队首元素
#include<iostream>
using namespace std;
const int maxn = 1005;
class Priority_queue {
public:
Priority_queue():len(0) {}
///添加元素
int Push(int num) {
if(len >= maxn-1)
return -1;
m_queue[++len] = num;
int j = len;
while(j != 1) {
int p = j/2;
if(m_queue[p] > num) {
m_queue[j] = m_queue[p];
m_queue[p] = num;
}
j/=2;
}
}
///队首元素
int Front() {
if(len == 0)
return -1;
return m_queue[1];
}
///删除队首元素
int Pop() {
if(len > 0) {
m_queue[1] = m_queue[len];
--len;
int i=1;
while(i*2 <= len) {
int j = i*2;
int index, minx;
if(i*2+1 <= len) {
if(m_queue[j] < m_queue[j+1]) {
minx = m_queue[j];
index = j;
} else {
minx = m_queue[j+1];
index = j+1;
}
} else {
index=j;
}
if(m_queue[i] > minx) {
int temp = m_queue[i];
m_queue[i] = m_queue[index];
m_queue[index] = temp;
}
i = index;
}
return 0;
}
return -1;
}
///返回队的长度
int size() {
return len;
}
private:
int m_queue[maxn];
int len;
};
int main() {
int n, t;
cin >> n;
Priority_queue que;
for(int i=0; i<n; i++) {
cin >> t;
que.Push(t);
}
for(int i=0; i<que.size(); i++) {
while(que.size() != 0) {
cout << que.Front() << " ";
que.Pop();
}
}
}
运行结果
*注 本文只是简单的实现优先队列,对一些异常情况没有讨论,仅供学习使用。