STL源码剖析 [容器](八)[priority_queue]
来源:互联网 发布:fsockopen php 开启 编辑:程序博客网 时间:2024/05/22 02:21
priority_queue,首先它是一个queue,即只允许在低端加入元素,并从顶端取出元素,除此之外别无其他存取元素的途径(故priority_queue不提供遍历功能,也不提供迭代器);再次它具有priority,即queue中的元素具有一定的priority:其内的元素自动依照元素的权值排列,权值最高者(也就是数值最高),排在最前面。注:在queue并非是依照严格的权值递减的顺序排列,而是每次保持顶端(对头)元素为queue中权值最高的元素(其内部采用heap来实现(默认是max heap))。
下面是stl_queue.h中的priority_queue源码:
class priority_queue{public: typedef typename Sequence::value_type value_type; typedef typename Sequence::size_type size_type; typedef typename Sequence::reference reference; typedef typename Sequence::const_reference const_reference;protected: Sequencec; // 底层容器 Compare comp; // 元素大小比较标准public: priority_queue(): c() {} explicit priority_queue(constCompare& x) : c(), comp(x) {} // 以下用到的make_heap(), push_heap(),pop_heap()都是泛型算法// 注意,任何一个构造函数都立刻于底层容器内产生一个implicitrepresentation heap。#ifdef __STL_MEMBER_TEMPLATES template <class InputIterator> priority_queue(InputIteratorfirst, InputIterator last, const Compare& x) : c(first, last), comp(x) { make_heap(c.begin(),c.end(), comp); } template <class InputIterator> priority_queue(InputIteratorfirst, InputIterator last) : c(first, last) { make_heap(c.begin(),c.end(), comp); }#else /* __STL_MEMBER_TEMPLATES */ priority_queue(constvalue_type* first, const value_type* last, const Compare& x) :c(first, last), comp(x) { make_heap(c.begin(), c.end(), comp); } priority_queue(constvalue_type* first, const value_type* last) : c(first, last) { make_heap(c.begin(),c.end(), comp); }#endif /* __STL_MEMBER_TEMPLATES */ bool empty()const { return c.empty(); } size_type size()const { return c.size(); } const_reference top()const { return c.front(); } void push(constvalue_type& x) { __STL_TRY { // push_heap 是泛型算法,先利用底层容器的push_back()将新元素 // 推入末端,再重排heap c.push_back(x); push_heap(c.begin(), c.end(), comp);// push_heap 是泛型演算法 } __STL_UNWIND(c.clear()); } void pop(){ __STL_TRY { // pop_heap 是泛型演算法,從 heap 內取出一個元素。它並不是真正將元素 // 彈出,而是重排heap,然後再以底層容器的pop_back() 取得被彈出 // 的元素。見C++ Primerp.1195。 pop_heap(c.begin(), c.end(), comp); c.pop_back(); } __STL_UNWIND(c.clear()); }};
priority_queue的使用示例1:
#include <iostream>#include <queue>using namespace std;class myComparison{ bool reverse;public: myComparison(const bool& revParam = false) { reverse = revParam; } bool operator()(const int& lhs, const int& rhs) const { if(reverse) return (lhs > rhs); else return (lhs < rhs); }};int main(){ int myInts[] = {10, 60, 50 ,20}; priority_queue<int> first; priority_queue<int> second(myInts, myInts+4); cout << "second size: " << second.size() << endl; cout << "second top: " << second.top() << endl; second.push(100); cout << "second top: " << second.top() << endl; priority_queue<int, vector<int>, greater<int> > third(myInts, myInts+4); cout << "third size: " << third.size() << endl; cout << "third top: " << third.top() << endl; third.push(100); cout << "third top: " << third.top() << endl; //using myComparison priority_queue<int, vector<int>, myComparison > fourth; typedef priority_queue<int, vector<int>, myComparison> myPq_type; myPq_type fifth(myComparison() ); myPq_type sixth(myInts, myInts+4, myComparison(true) ); cout << "sixth top: " << sixth.top() << endl; sixth.pop(); cout << "sixth top: " << sixth.top() << endl; return 0;}
priority_queue的使用范例2:
//优先级队列 priority_queue by MoreWindows( http://blog.csdn.net/MoreWindows )// 支持 empty() size() top() push() pop() 与stack的操作函数全部一样//by MoreWindows#include <queue>#include <list>#include <cstdio>using namespace std;int main(){//优先级队列默认是使用vector作容器。priority_queue<int> a;priority_queue<int, list<int>> b; //可以这样声明,但无法使用int i;//压入数据for (i = 0; i < 10; i++){a.push(i * 2 - 5);//b.push(i); //编译错误}//优先级队列的大小printf("%d\n", a.size());//取优先级队列数据并将数据移出队列while (!a.empty()){printf("%d ", a.top());a.pop();}putchar('\n');return 0;}
下面程序是针对结构体的,对数据的比较是通过对结构体重载operator()。
程序功能是模拟排队过程,每人有姓名和优先级,优先级相同则比较姓名,开始有5个人进入队列,然后队头2个人出队,再有3个人进入队列,最后所有人都依次出队,程序会输出离开队伍的顺序。
//by MoreWindows( http://blog.csdn.net/MoreWindows )#include <queue>#include <cstring>#include <cstdio>using namespace std;//结构体struct Node{char szName[20];int priority;Node(int nri, char *pszName){strcpy(szName, pszName);priority = nri;}};//结构体的比较方法 改写operator()struct NodeCmp{bool operator()(const Node &na, const Node &nb){if (na.priority != nb.priority)return na.priority <= nb.priority;elsereturn strcmp(na.szName, nb.szName) > 0;}};void PrintfNode(Node &na){printf("%s %d\n", na.szName, na.priority);}int main(){//优先级队列默认是使用vector作容器,底层数据结构为堆。priority_queue<Node, vector<Node>, NodeCmp> a;//有5个人进入队列a.push(Node(5, "小谭"));a.push(Node(3, "小刘"));a.push(Node(1, "小涛"));a.push(Node(5, "小王"));//队头的2个人出队PrintfNode(a.top());a.pop();PrintfNode(a.top());a.pop();printf("--------------------\n");//再进入3个人a.push(Node(2, "小白"));a.push(Node(2, "小强"));a.push(Node(3, "小新"));//所有人都依次出队while (!a.empty()){PrintfNode(a.top());a.pop();}return 0;}
将上面结构体Node改成类:
类code:
class Node{public:Node(int nri, char *pszName){strcpy(szName, pszName);priority = nri;}char* GetName();int GetPriority();char* GetName() const;int GetPriority() const;private:char szName[20];int priority;};char* Node::GetName(){return szName;}int Node::GetPriority(){return priority;}char* Node::GetName() const{return (char*)szName;}int Node::GetPriority() const{return priority;}inline bool operator < (const Node &na, const Node &nb){if (na.GetPriority() != nb.GetPriority())return na.GetPriority() <= nb.GetPriority();elsereturn strcmp(na.GetName(), nb.GetName()) > 0;}
程序code:
#include <queue>#include <cstring>#include <cstdio>using namespace std; void PrintfNode(Node &na){printf("%s %d\n", na.GetName(), na.GetPriority());}int main(){//优先级队列默认是使用vector作容器,底层数据结构为堆。priority_queue<Node> a;//有5个人进入队列a.push(Node(5, "小谭"));a.push(Node(3, "小刘"));a.push(Node(1, "小涛"));a.push(Node(5, "小王"));//队头的2个人出队PrintfNode(a.top());a.pop();PrintfNode(a.top());a.pop();printf("--------------------\n");//再进入3个人a.push(Node(2, "小白"));a.push(Node(2, "小强"));a.push(Node(3, "小新"));//所有人都依次出队while (!a.empty()){PrintfNode(a.top());a.pop();}return 0;}
0 0
- STL源码剖析 [容器](八)[priority_queue]
- STL源码剖析——容器配接器之priority_queue
- STL源码剖析 - 第4章 序列式容器 - priority_queue
- STL之priority_queue源码剖析
- 《STL源码剖析》容器
- 【STL源码剖析读书笔记】【第4章】序列式容器之heap和priority_queue
- STL 源码剖析读书笔记五:序列式容器之 heap、priority_queue、slist
- STL源码剖析-序列式容器之heap和priority_queue
- STL 之 queue、priority_queue 源码剖析
- STL源码剖析——priority_queue
- STL源码剖析(4):容器(vector)
- STL源码剖析(4):容器(list)
- STL源码剖析 [容器](二)
- STL源码剖析 [容器](十二)[RB_Tree]
- STL源码剖析笔记(二)---容器
- STL源码剖析---关联容器
- 《stl源码剖析》--关联容器
- 《STL源码剖析》之容器
- Python入门
- 华为面试:字符逆序
- Android帮助文档本地打开慢的解决方案
- HashSet练习 根据用户名密码注册账户
- Senior's Gun-------(BestCoder Round #47)
- STL源码剖析 [容器](八)[priority_queue]
- WinSCP:支持与linux互传的windows端的图形化SCP
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
- iOS中属性与成员变量的区别
- 普通表向分区表转换的几种方法(转载yangtingkun blog)
- 项目整合心得
- hdu 5423 Rikka with Tree
- HDU 3397 Sequence operation(线段树区间合并)
- maven的profile