转自博客:
http://blog.youkuaiyun.com/yuanjilai/article/details/8043157
优先队列容器默认使用向量容器实现,用户也可以使用双端队列容器。优先队列总是把优先级最高的元素放在队列的最前方,来保持队列的有序性。
插入操作push()使用一个双变量的布尔函数,将队列中的元素重新排序,以满足这个要求。
该函数可以由用户提供,否则可以使用<操作符,元素越大,优先级越高。
如果元素越小,优先级越高,则需要使用函数对象greater,表明在决定向优先级队列中插入新元素时,push()应该使用的操作符是>而不是<.
成员函数:
empty | true if the priority queue has no elements |
pop | removes the top element of a priority queue |
push | adds an element to the end of the priority queue |
size | returns the number of items in the priority queue |
top | returns the top element of the priority queue |
在优先队列中,优先级高的元素先出队列。标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。
优先队列的第一种用法,也是最常用的用法:
- priority_queue<int> qi;
通过<操作符可知在整数中元素大的优先级高。
故示例1中输出结果为:9 6 5 3 2
第二种方法:
在示例1中,如果我们要把元素从小到大输出怎么办呢?
这时我们可以传入一个比较函数,使用functional.h函数对象作为比较函数。
- priority_queue<int, vector<int>, greater<int> > qi2;
其中
第二个参数为容器类型。
第三个参数为比较函数。
故示例2中输出结果为:2 3 5 6 9
第三种方法:自定义优先级。
- struct node
- {
- friend bool operator< (node n1, node n2)
- {
- return n1.priority < n2.priority;
- }
- int priority;
- int value;
- };
在该结构中,value为值,priority为优先级。
通过自定义operator<操作符来比较元素中的优先级。
在示例3中输出结果为:
优先级 值
9 5
8 2
6 1
2 3
1 4
但如果结构定义如下:
- struct node
- {
- friend bool operator> (node n1, node n2)
- {
- return n1.priority > n2.priority;
- }
- int priority;
- int value;
- };
则会编译不过(G++编译器)因为标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。而且自定义类型的<操作符与>操作符并无直接联系,故会编译不过。
//代码清单
- #include<iostream>
- #include<functional>
- #include<queue>
- using namespace std;
- struct node
- {
- friend bool operator< (node n1, node n2)
- {
- return n1.priority < n2.priority;
- }
- int priority;
- int value;
- };
- int main()
- {
- const int len = 5;
- int i;
- int a[len] = {3,5,9,6,2};
- //示例1
- priority_queue<int> qi;
- for(i = 0; i < len; i++)
- qi.push(a[i]);
- for(i = 0; i < len; i++)
- {
- cout<<qi.top()<<" ";
- qi.pop();
- }
- cout<<endl;
- //示例2
- priority_queue<int, vector<int>, greater<int> >qi2;
- for(i = 0; i < len; i++)
- qi2.push(a[i]);
- for(i = 0; i < len; i++)
- {
- cout<<qi2.top()<<" ";
- qi2.pop();
- }
- cout<<endl;
- //示例3
- priority_queue<node> qn;
- node b[len];
- b[0].priority = 6; b[0].value = 1;
- b[1].priority = 9; b[1].value = 5;
- b[2].priority = 2; b[2].value = 3;
- b[3].priority = 8; b[3].value = 2;
- b[4].priority = 1; b[4].value = 4;
- for(i = 0; i < len; i++)
- qn.push(b[i]);
- cout<<"优先级"<<'\t'<<"值"<<endl;
- for(i = 0; i < len; i++)
- {
- cout<<qn.top().priority<<'\t'<<qn.top().value<<endl;
- qn.pop();
- }
- return 0;
- }
另外贴一段优先队列使用的代码:
- #include<iostream>
- #include<functional>
- #include<queue>
- #include<vector>
- using namespace std;
- struct cmp1
- {
- bool operator () (int &a, int &b)
- {
- return a > b ; // 从小到大排序,值 小的 优先级别高
- }
- };
- struct cmp2
- {
- bool operator () (int &a, int &b)
- {
- return a < b; // 从大到小
- }
- };
- struct number1
- {
- int x;
- bool operator < (const number1 &a)const
- {
- return x > a.x; // 从小到大 ,x 小的 优先级别高
- }
- };
- struct number2
- {
- int x;
- bool operator < (const number2 &a)const
- {
- return x < a.x; // 从大到小 ,x 大的优先级别高
- }
- };
- int a[] = {14,10,56,7,83,22,36,91,3,47,72,0};
- number1 num1[] ={14,10,56,7,83,22,36,91,3,47,72,0};
- number2 num2[] ={14,10,56,7,83,22,36,91,3,47,72,0};
- int main()
- {
- priority_queue<int>que; // 采用默认优先级构造队列 从大到小。
- priority_queue<int, vector<int>, cmp1 >que1;
- priority_queue<int, vector<int>, cmp2 >que2;
- priority_queue<int, vector<int>, greater<int> > que3; //functional 头文件自带的
- priority_queue<int, vector<int>, less<int> > que4; //functional 头文件自带的
- priority_queue<number1> que5;
- priority_queue<number2> que6;
- int i;
- for(i=0;a[i];i++)
- {
- que.push(a[i]);
- que1.push(a[i]);
- que2.push(a[i]);
- que3.push(a[i]);
- que4.push(a[i]);
- }
- for(i=0;num1[i].x;i++)
- que5.push(num1[i]);
- for(i=0;num2[i].x;i++)
- que6.push(num2[i]);
- printf("采用默认优先关系:\n(priority_queue<int>que;)\n");
- printf("Queue 0:\n");
- while(!que.empty())
- {
- printf("%3d",que.top());
- que.pop();
- }
- puts("");
- puts("");
- printf("采用结构体自定义优先级方式一:\n(priority_queue<int,vector<int>,cmp>que;)\n");
- printf("Queue 1:\n");
- while(!que1.empty())
- {
- printf("%3d",que1.top());
- que1.pop();
- }
- puts("");
- printf("Queue 2:\n");
- while(!que2.empty())
- {
- printf("%3d",que2.top());
- que2.pop();
- }
- puts("");
- puts("");
- printf("采用头文件\"functional\"内定义优先级:\n(priority_queue<int, vector<int>,greater<int>/less<int> >que;)\n");
- printf("Queue 3:\n");
- while(!que3.empty())
- {
- printf("%3d",que3.top());
- que3.pop();
- }
- puts("");
- printf("Queue 4 :\n");
- while(!que4.empty())
- {
- printf("%3d",que4.top());
- que4.pop();
- }
- puts("");
- puts("");
- printf("采用结构体自定义优先级方式二:\n(priority_queue<number>que)\n");
- printf("Queue 5:\n");
- while(!que5.empty())
- {
- printf("%3d",que5.top());
- que5.pop();
- }
- puts("");
- printf("Queue 6:\n");
- while(!que6.empty())
- {
- printf("%3d",que6.top());
- que6.pop();
- }
- return 0;
- }
执行结果:
九月网易有道招聘上机题:
给出大小为N的数组,用最快的办法找出前M个大的数字。
- #include <iostream>
- #include <functional>
- #include <queue>
- using namespace std;
- int main()
- {
- priority_queue<int,vector<int>, greater<int> > q;//从小到大
- int n,m,num;
- while (cin>>n>>m)
- {
- int i;
- for (i = 0; i < m; i ++)
- {
- cin>>num;
- q.push(num);
- }
- for (; i < n; i ++)
- {
- cin>>num;
- if (num > q.top())
- {
- q.pop();
- q.push(num);
- }
- }
- while (!q.empty())
- {
- cout<<q.top()<<" ";
- q.pop();
- }
- cout<<endl;
- }
- return 0;
- }
这个题目可以用一个大小是M的最小堆来实现,初始建堆用数组前M个建好后,如果后面的元素a[i] 大于堆顶元素,那么就删除堆顶,插入新的元素。