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

 

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

插入操作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

 

 

 

阅读更多
个人分类: STL
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭