1. 程式人生 > >STL系列之五 priority queue 優先順序佇列

STL系列之五 priority queue 優先順序佇列

priority_queue 優先順序佇列是一個擁有權值概念的單向佇列queue,在這個佇列中,所有元素是按優先順序排列的(也可以認為queue是個按進入佇列的先後做為優先順序的優先順序佇列——先進入佇列的元素優先權要高於後進入佇列的元素)。在計算機作業系統中,優先順序佇列的使用是相當頻繁的,進執行緒排程都會用到。在STL的具體實現中,priority_queue也是以別的容器作為底部結構,再根據堆的處理規則來調整元素之間的位置。下面給出priority_queue的函式列表和VS2008中priority_queue的原始碼,本文中與heap有關的函式參見《STL系列之四 heap 堆》

priority_queue函式列表
函式 描述      by MoreWindows( http://blog.csdn.net/MoreWindows )
構造析構
 
priority_queue <Elem> c
 建立一個空的queue 。
注:priority_queue建構函式有7個版本,請查閱MSDN
資料訪問與增減
 
c.top()
返回佇列頭部資料
c.push(elem) 在佇列尾部增加elem資料
 c.pop() 佇列頭部資料出隊
其它操作
 
c.empty() 判斷佇列是否為空
c.size()

返回佇列中資料的個數

   

可以看出priority_queue的函式列表與棧stack的函式列表是相同的。

 

VS2008中priority_queue 優先順序佇列的原始碼

友情提示:初次閱讀時請注意其實現思想,不要在細節上浪費過多的時間

 

//VS2008中 priority_queue的定義 MoreWindows整理( http://blog.csdn.net/MoreWindows )
template<class _Ty, class _Container = vector<_Ty>, class _Pr = less<typename _Container::value_type> > //預設以vector為容器的
class priority_queue
{	// priority queue implemented with a _Container
public:
	typedef _Container container_type;
	typedef typename _Container::value_type value_type;
	typedef typename _Container::size_type size_type;
	typedef typename _Container::reference reference;
	typedef typename _Container::const_reference const_reference;

	priority_queue() : c(), comp()
	{	// construct with empty container, default comparator
	}

	explicit priority_queue(const _Pr& _Pred) : c(), comp(_Pred)
	{	// construct with empty container, specified comparator
	}

	priority_queue(const _Pr& _Pred, const _Container& _Cont) : c(_Cont), comp(_Pred)
	{	// construct by copying specified container, comparator
		make_heap(c.begin(), c.end(), comp); //參見《STL系列之四 heap 堆的相關函式》
	}

	template<class _Iter>
	priority_queue(_Iter _First, _Iter _Last) : c(_First, _Last), comp()
	{	// construct by copying [_First, _Last), default comparator
		make_heap(c.begin(), c.end(), comp);
	}

	template<class _Iter>
	priority_queue(_Iter _First, _Iter _Last, const _Pr& _Pred) : c(_First, _Last), comp(_Pred)
	{	// construct by copying [_First, _Last), specified comparator
		make_heap(c.begin(), c.end(), comp);
	}

	template<class _Iter>
	priority_queue(_Iter _First, _Iter _Last, const _Pr& _Pred, const _Container& _Cont) : c(_Cont), comp(_Pred)
	{	// construct by copying [_First, _Last), container, and comparator
		c.insert(c.end(), _First, _Last);
		make_heap(c.begin(), c.end(), comp);
	}

	bool empty() const
	{	// test if queue is empty
		return (c.empty());
	}

	size_type size() const
	{	// return length of queue
		return (c.size());
	}

	const_reference top() const
	{	// return highest-priority element
		return (c.front());
	}

	reference top()
	{	// return mutable highest-priority element (retained)
		return (c.front());
	}

	void push(const value_type& _Pred)
	{	// insert value in priority order
		c.push_back(_Pred);
		push_heap(c.begin(), c.end(), comp);
	}

	void pop()
	{	// erase highest-priority element
		pop_heap(c.begin(), c.end(), comp);
		c.pop_back();
	}

protected:
	_Container c;	// the underlying container
	_Pr comp;	// the comparator functor
};

下面先給出優級先級佇列的使用範例。

//優先順序佇列 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;
		else
			return 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改成類來試下,答案2天后發到本篇的評論中。

 

 

轉載請標明出處,原文地址:http://blog.csdn.net/morewindows/article/details/6976468

 

再分享一下我老師大神的人工智慧教程吧。零基礎!通俗易懂!風趣幽默!希望你也加入到我們人工智慧的隊伍中來!http://www.captainbed.net