您的位置:首页 > 产品设计 > UI/UE

标准模板库STL中优先队列Priority Queues使用手册

2012-10-06 14:56 721 查看
优先队列容器默认使用向量容器实现,用户也可以使用双端队列容器。优先队列总是把优先级最高的元素放在队列的最前方,来保持队列的有序性。

插入操作push()使用一个双变量的布尔函数,将队列中的元素重新排序,以满足这个要求。

该函数可以由用户提供,否则可以使用<操作符,元素越大,优先级越高。

如果元素越小,优先级越高,则需要使用函数对象greater,表明在决定向优先级队列中插入新元素时,push()应该使用的操作符是>而不是<.

成员函数:

emptytrue if the priority queue has no elements

popremoves the top element of a priority queue

pushadds an element to the end of the priority queue

sizereturns the number of items in the priority queue

topreturns 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

/article/10030161.html

/article/7616133.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: