一、概述
priority_queue,首先它是一个queue,即只允许在低端加入元素,并从顶端取出元素,除此之外别无其他存取元素的途径(故priority_queue不提供遍历功能,也不提供迭代器);再次它具有priority,即queue中的元素具有一定的priority:其内的元素自动依照元素的权值排列,权值最高者(也就是数值最高),排在最前面。
注:在queue并非是依照严格的权值递减的顺序排列,而是每次保持顶端(对头)元素为queue中权值最高的元素(其内部采用heap来实现(默认是max heap))。
二、实现
由于priority_queue完全以底部容器为根据,在加上heap处理规则,所以其实现较简单,且缺省情况下以vector为底部容器。
联系适配器(adapter)的定义:具有这种【修改某物接口,形成另一种风貌】之性质者,称为adapter。因为,STL priority_queue被归类为:Container adapter 。
其SGI(Silicon Graphics Computer Systems, Inc.) STL中的priority_queue的源码如下:
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/* NOTE: This is an internal header file, included by other STL headers.
* You should not attempt to use it directly.
*/
#ifndef __SGI_STL_INTERNAL_QUEUE_H
#define __SGI_STL_INTERNAL_QUEUE_H
__STL_BEGIN_NAMESPACE
// 如果编译器不能根据前面模板参数推导出后面使用的默认参数类型,
// 那么就需要手工指定, 本实作queue内部容器默认使用deque
// 由于queue要求在队尾追加元素, 在队头获取和移除元素
// 所以非常适合使用deque
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template >
#else
template
#endif
class queue
{
// 讲解见中的运算符剖析
friend bool operator== __STL_NULL_TMPL_ARGS (const queue& x, const queue& y);
friend bool operator< __STL_NULL_TMPL_ARGS (const queue& x, const queue& y);
public:
// 由于queue仅支持对队头和队尾的操作, 所以不定义STL要求的
// pointer, iterator, difference_type
typedef typename Sequence::value_type value_type;
typedef typename Sequence::size_type size_type;
typedef typename Sequence::reference reference;
typedef typename Sequence::const_reference const_reference;
protected:
Sequence c; // 这个是我们实际维护的容器
public:
// 这些是STL queue的标准接口, 都调用容器的成员函数进行实现
// 其接口和stack实现很接近, 参考
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
reference front() { return c.front(); }
const_reference front() const { return c.front(); }
reference back() { return c.back(); }
const_reference back() const { return c.back(); }
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_front(); }
};
// 详细讲解见
template
bool operator==(const queue& x, const queue& y)
{
return x.c == y.c;
}
template
bool operator<(const queue& x, const queue& y)
{
return x.c < y.c;
}
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template ,
class Compare = less >
#else
template
#endif
class priority_queue
{
public:
typedef typename Sequence::value_type value_type;
typedef typename Sequence::size_type size_type;
typedef typename Sequence::reference reference;
typedef typename Sequence::const_reference const_reference;
protected:
Sequence c; // 内部维护的容器
Compare comp; // 优先级决策判别式
public:
priority_queue() : c() {}
// 用户可以指定自己的优先级决策函数
explicit priority_queue(const Compare& x) : c(), comp(x) {}
// 使用[first, last)区间构造priority_queue
#ifdef __STL_MEMBER_TEMPLATES
template
priority_queue(InputIterator first, InputIterator last, const Compare& x)
: c(first, last), comp(x) { make_heap(c.begin(), c.end(), comp); }
template
priority_queue(InputIterator first, InputIterator last)
: c(first, last) { make_heap(c.begin(), c.end(), comp); }
#else /* __STL_MEMBER_TEMPLATES */
priority_queue(const value_type* first, const value_type* last,
const Compare& x) : c(first, last), comp(x) {
make_heap(c.begin(), c.end(), comp);
}
priority_queue(const value_type* first, const value_type* last)
: c(first, last) { make_heap(c.begin(), c.end(), comp); }
#endif /* __STL_MEMBER_TEMPLATES */
// STL priority_queue标准接口
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
// 返回优先级最高的元素
const_reference top() const { return c.front(); }
// 插入元素, 并调整heap
void push(const value_type& x)
{
__STL_TRY {
c.push_back(x);
// 详细分析见
push_heap(c.begin(), c.end(), comp);
}
__STL_UNWIND(c.clear());
}
// 弹出优先级最高的元素
void pop() {
__STL_TRY {
// 详细分析见
pop_heap(c.begin(), c.end(), comp);
c.pop_back();
}
__STL_UNWIND(c.clear());
}
};
// 不提供比较操作
__STL_END_NAMESPACE
#endif /* __SGI_STL_INTERNAL_QUEUE_H */
// Local Variables:
// mode:C++
// End:
注:
class Compare = less
三、测试实例
#include
#include
using namespace std;
class myComparison
{
bool reverse;
public:
myComparison(const bool& revParam = false)
{
reverse = revParam;
}
bool operator()(const int& lhs, const int& rhs) const
{
if(reverse)
return (lhs > rhs);
else
return (lhs < rhs);
}
};
int main()
{
int myInts[] = {10, 60, 50 ,20};
priority_queue first;
priority_queue second(myInts, myInts+4);
cout << "second size: " << second.size() << endl;
cout << "second top: " << second.top() << endl;
second.push(100);
cout << "second top: " << second.top() << endl;
priority_queue, greater > third(myInts, myInts+4);
cout << "third size: " << third.size() << endl;
cout << "third top: " << third.top() << endl;
third.push(100);
cout << "third top: " << third.top() << endl;
//using myComparison
priority_queue, myComparison > fourth;
typedef priority_queue, myComparison> myPq_type;
myPq_type fifth(myComparison() );
myPq_type sixth(myInts, myInts+4, myComparison(true) );
cout << "sixth top: " << sixth.top() << endl;
sixth.pop();
cout << "sixth top: " << sixth.top() << endl;
return 0;
}