标准模板库STL中优先队列Priority Queues使用手册
优先队列容器默认使用向量容器实现,用户也可以使用双端队列容器。优先队列总是把优先级最高的元素放在队列的最前方,来保持队列的有序性。插入操作push()使用一个双变量的布尔函数,将队列中的元素重新排序,以满足这个要求。该函数可以由用户提供,否则可以使用如果元素越小,优先级越高,则需要使用函数对象greater,表明在决定向优先级队列中插入新元素时,push()应该使用的操作符是>而不是
优先队列容器默认使用向量容器实现,用户也可以使用双端队列容器。优先队列总是把优先级最高的元素放在队列的最前方,来保持队列的有序性。
插入操作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] 大于堆顶元素,那么就删除堆顶,插入新的元素。
参考文章:
http://www.cppblog.com/shyli/archive/2007/04/06/21366.html
http://blog.csdn.net/yidujinhuang/article/details/6868093
http://blog.csdn.net/hopeztm/article/details/8026457
更多推荐
所有评论(0)