Priority Queues优先级队列详解

概述

STL中 class priority_queue<>实作出一个queue,其中的元素根据优先级被读取,top() / pop()移除/存取下一个元素。这里的“下一个元素”是指“优先级最高”的元素。即priority_queue内的元素已经根据其值进行了排序。

在priority_queue和queue都定义于头文件<queue>

namespace std
{
	template <class T,
	          class Container = vector<T> ,
			  Class Compare = less<tyname Container::value_type> >
	Class priority_queue;
}


第一个template参数是元素类型,第二个template参数定义了内部元素实际存放的容器,默认是vector,但必须要支持存取随机迭代器。第三个template参数是“用以搜寻下一个最高优先级元素”的排序准则。默认是以operator<作为比较标准,图1展示了priority_queue的接口。

核心接口

priority_queue的核心接口主要由成员函数push(),top(),pop()组成:
push()
  • 将一个元素置入priority_queue内.
pop()
  • 移除priority_queue中“优先级最高”的元素,如果存在多个相等的元素,则无法确知会移除哪一个.
  • 调用者保证priority_queue非空.
  • 该函数无返回值,想处理被移除的元素,需要调用top().
top()
  • 从priority_queue中返回“优先级最高的元素”,如果存在多个相等的元素,则无法确知会返回哪一个.
  • 调用者必须保证priority_queue非空,否则会导致未定义行为.

源码实现

template<class _Ty,
	class _Container = vector<_Ty>,
	class _Pr = less<typename _Container::value_type> >
	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);
		}

	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
	};

应用实例

/****************************************************************
*函数名称:PriorityQueuesTest
*功    能:优先级队列使用说明
*作    者:Jin
*日    期:2016年7月6日
****************************************************************/
void PriorityQueuesTest()
{
    priority_queue<int> PriorityQue;
    
    //insert elements into priority queue
    PriorityQue.push(66);
    PriorityQue.push(22);
    PriorityQue.push(44);
    cout <<"insert num to priority queue : 66 22 44" << endl;

    //read and print two elements
    cout <<"read first element and pop it: " << PriorityQue.top() << endl;
    PriorityQue.pop();
    cout << "read second element and pop it: " << PriorityQue.top() << endl;
    PriorityQue.pop();

    //insert three more elements
    PriorityQue.push(11);
    PriorityQue.push(55);
    PriorityQue.push(33);
    cout <<"insert num to priority queue : 11 55 33" << endl;
    
    //pop one elements without dealing data
    cout << "pop one elements" << endl;
    PriorityQue.pop();

    //pop and print remaining element
    cout << "pop and print remaining element:" << endl;
    while (!PriorityQue.empty())
    {
        cout << PriorityQue.top() << ' ';
        PriorityQue.pop();
    }
    cout << endl;
}
运行结果:


posted @ 2016-07-13 21:57  小怪兽&奥特曼  阅读(897)  评论(0编辑  收藏  举报