目录
前言
优先级队列(priority_queue)是一种特殊的队列数据结构,其中每个元素都有一个“优先级”。优先级最高的元素最先出队,而优先级最低的元素则最后出队。元素优先级的高低通常由它的值决定。
用法介绍
//传迭代器区间构造
template <class InputIterator>
priority_queue (InputIterator first, InputIterator last,const Compare& comp = Compare(),
const Container& ctnr = Container());
//插入
void push(const value_type& val);
//弹出队头
void pop();
//返回队头元素但不删除
const_reference top() const;
//队列中的数据个数
size_type size() const;
//判断队列是否为空
bool empty() const;
其中,上述构造函数的第三个参数为仿函数,在下面的实现中将会介绍。
模拟实现
底层用vector实现。
仿函数
仿函数其实是一个重载了operator()的类,使得该类的对象在调用operator()是看起来像函数调用一样。
struct less
{
bool operator()(int x, int y)
{
return x < y;
}
};
int main()
{
less cmp;
cmp(1, 2);//像函数一样调用
return 0;
}
迭代器区间构造
1)将该区间内的所有元素插入vector中
2)向下调整建堆
代码:
template<class InputIterator>
priority_queue(InputIterator first, InputIterator last)
{
while (first != last)
{
_con.push_back(*first);
++first;
}
for (int i = (_con.size() - 2) / 2; i >= 0; i--)
{
AdjustDown(i);
}
}
插入
1)复用底层vector插入数据
2)向上调整
代码:
void push(const T& x)
{
_con.push_back(x);
AdjustUp(_con.size() - 1);
}
删除
1)堆顶元素与最后一个元素交换
2)复用底层vector的尾删
3)从堆顶开始向下调整
代码:
void pop()
{
swap(_con[0], _con[_con.size() - 1]);
_con.pop_back();
AdjustDown(0);
}
队顶
直接返回vector的头即可。
代码:
const T& top()
{
return _con[0];
}
判空
vector为空,则优先级队列为空。
代码:
bool empty()
{
return _con.empty();
}
大小
vector的size就是优先级队列的size。
代码:
size_t size()
{
return _con.size();
}
完整代码
#include <vector>
#include <iostream>
using namespace std;
namespace pcz
{
//仿函数
template<class T>
struct less
{
bool operator()(const T& x, const T& y)
{
return x < y;
}
};
template<class T>
struct greater
{
bool operator()(const T& x, const T& y)
{
return x > y;
}
};
template<class T, class Container = vector<T>, class Compare = less<T>>
class priority_queue
{
public:
priority_queue() : _con() { }
template<class InputIterator>
priority_queue(InputIterator first, InputIterator last)
{
while (first != last)
{
_con.push_back(*first);
++first;
}
for (int i = (_con.size() - 2) / 2; i >= 0; i--)
{
AdjustDown(i);
}
}
void push(const T& x)
{
_con.push_back(x);
AdjustUp(_con.size() - 1);
}
void pop()
{
swap(_con[0], _con[_con.size() - 1]);
_con.pop_back();
AdjustDown(0);
}
const T& top()
{
return _con[0];
}
size_t size()
{
return _con.size();
}
bool empty()
{
return _con.empty();
}
void AdjustUp(int child)
{
int parent = (child - 1) / 2;
while (child > 0)
{
//仿函数
if (comp(_con[parent], _con[child]))
{
swap(_con[parent], _con[child]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
void AdjustDown(int parent)
{
int child = parent * 2 + 1;
while (child < _con.size())
{
//仿函数
if (child + 1 < _con.size() && comp(_con[child], _con[child + 1]))
child++;
if (comp(_con[parent], _con[child]))
{
swap(_con[parent], _con[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
protected:
Container _con;//底层容器
Compare comp; //元素大小比较标准
};
}
#include "priority_queue.h"
int main()
{
int a[] = { 0,1,2,3,4,8,9,3,5 };
pcz::priority_queue<int> q(a, a + 9);
while (!q.empty())
{
cout << q.top() << " ";
q.pop();
}
cout << endl;
return 0;
}