首先我们要了解什么是 priority_queue ,priority_queue 优先队列是一种数据结构,它存储了元素以及它们的优先级。在优先队列中,元素按照其优先级的顺序进行移除,优先级较高的元素首先被移除。优先队列通常使用堆数据结构来实现,这样可以实现根据优先级高低高效地插入和移除元素。
而如何控制优先级比较就可以快速的进行建堆操作,此外,我们还可以使用不同的容器来进行实现 优先级队列。因此,看似简单的 优先级队列,我们通过 模板、仿函数 的封装,也能玩出花来。话不多说,上代码。
#include<iostream>
#include<list>
#include<vector>
using namespace std;
namespace test
{template <class T>struct Less// 大堆//com(_con[parent],_con[child]){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>struct GreaterPtr{bool operator()(const T& p1, const T& p2){return *p1 > *p2;}};//仿函数可以控制比较逻辑,也可以进行多种类型之间的比较//每一次比较够可以通过 给定的 仿函数类型//进行特定的比较//虽然只重载了 () 但是真nb//当然也可以对仿函数进行 特化处理 用来针对特殊参数类型template <class T>struct Greater<T*>{bool operator()(const T* x, const T* y){return *x > *y;}};//priority_queuetemplate<class T, class Container = vector<T>, class Compare = less<T>>// Container 使用 deque 也可以适配//优先级队列class priority_queue//默认是大堆 less{public:void adjust_up(size_t child){Compare com;// less<T>size_t parent = (child - 1) / 2;while (child > 0){//if (_con[child] > _con[parent])// < 大堆 less > 小堆 greater//if (_con[parent] < _con[child])if (com(_con[parent], _con[child]))//大堆 <{swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}elsebreak;}}void push(const T& x)//尾部插入,向上调整{_con.push_back(x);adjust_up(_con.size() - 1);//向上调整}void adjust_down(size_t parent){Compare com;// less<T>size_t child = parent * 2 + 1;//左孩子while (child < _con.size()){//if (child + 1 < _con.size() && _con[child + 1] > _con[child])//if (child + 1 < _con.size() && _con[child] < _con[child+1])if (child + 1 < _con.size() && com(_con[child], _con[child + 1])){child++;//右孩子, 大堆,取较大的}//if (_con[child] > _con[parent])//if (_con[parent] < _con[child])if (com(_con[parent], _con[child])){swap(_con[child], _con[parent]);parent = child;child = parent * 2 + 1;}elsebreak;}}void pop()//删除堆顶,将首尾交换{swap(_con[0], _con[_con.size() - 1]);//首尾交换_con.pop_back();adjust_down(0);//向下调整}bool empty(){return _con.empty();}size_t size(){return _con.size();}const T& top(){return _con[0];}private:Container _con;};
}
int main()
{test::priority_queue<int,vector<int>, less<int>> pq;// test::priority_queue<int> pq; 等价与上,采用 缺省模板pq.push(50);pq.push(60);pq.push(20);pq.push(10);pq.push(40);pq.push(30);//建大堆while (!pq.empty()){cout << pq.top() << " ";pq.pop();}return 0;
}
运行结果:
在priority_queue的模板中:
template<class T, class Container = vector<T>, class Compare = less<T>>,
我们可以改变其中 默认 Container 的类型选择不同的容器来实现优先级队列,还可以通过 设置默认的 Compare 的仿函数来采用不同的 比较逻辑。可以看到,这个模拟实现的 priority_queue 有很强的自主性,其中仿函数的实现更是点睛之笔,一个简单的结构体就能实现多种类型的比较。
最近很喜欢苏轼的一首诗《水调歌头·黄州快哉亭赠张偓佺》赠给同学们!!!!!!!!!
落日绣帘卷,亭下水连空。知君为我新作,窗户湿青红。长记平山堂上,欹枕江南烟雨,杳杳没孤鸿。认得醉翁语,“山色有无中”。
一千顷,都镜净,倒碧峰。忽然浪起,掀舞一叶白头翁。堪笑兰台公子,未解庄生天籁,刚道有雌雄。一点浩然气,千里快哉风。