This context is similar to a heap where only the max heap element can be retrieved (the one at the top in the priority queue) and elements can be inserted indefinitely.
Priority queues are implemented as container adaptors, which are classes that use an encapsulated object of a specific container class as its underlying container, providing a specific set of member functions to access its elements. Elements are popped from the "back" of the specific container, which is known as the top of the priority queue.
The underlying container may be any of the standard container class templates or some other specifically designed container class. The only requirement is that it must be accessible through random access iterators and it must support the following operations:
Therefore, the standard container class templates vector and deque can be used. By default, if no container class is specified for a particular priority_queue class, the standard container class template vector is used.
Support for random access iterators is required to keep a heap structure internally at all times. This is done automatically by the container adaptor by calling the algorithms make_heap, push_heap and pop_heap when appropriate.
In their implementation in the C++ Standard Template Library, priority queues take three template parameters:
|
|
Where the template parameters have the following meanings:
In the reference for the priority_queue member functions, these same names (T, Container and Compare) are assumed for the template parameters.
Remove top element (public member function)
priority_queue <Elem> c |
创建一个空的queue 。 |
c.top() |
返回队列头部数据 |
c.push(elem) |
在队列尾部增加elem数据 |
c.pop() |
队列头部数据出队 |
c.empty() |
判断队列是否为空 |
c.size() |
返回队列中数据的个数 |
优先队列容器也是一种从一端入队,另一端出对的队列。不同于一般队列的是,队列中最大的元素总是位于队首位置,因此,元素的出对并非按照先进先出的要求,将最先入队的元素出对,而是将当前队列中的最大元素出对。 C++ STL 优先队列的泛化,底层默认采用 vector 向量容器,使得队列容器的元素可做数组操作,从而应用堆算法找出当前队列最大元素,并将它调整到队首位置,确保最大元素出队。堆算法(heap algorithm) 具有 nLog(n) 阶的算法时间复杂度,此外,优先队列也可看作容器适配器,将底层的序列容器 vector 转换为优先队列priority_queue.
priority_queue 优先队列容器的 C++ 标准头文件也是 queue ,需要用宏语句 "#include <queue>" 包含进来。
同样是因为仅需取队首和队尾元素的操作,因此 priority_queue 优先队列容器也不提供迭代器,对其他任意位置处的元素进行直接访问操作。使用时,一般用 priority_queue<T> 的形式进行具现, T 是优先队列元素的一个具现类型。
创建 priority_queue 对象
使用 priority_queue 队列之前,要先利用构造函数生成一个优先对象,才可进行元素的入队、出对、取队首及队尾等操作。
1. priority_queue()
默认的构造函数,创建一个空的 priority_queue 对象。例如,下面一行代码使用默认的 vector 为底层容器,创建了一个空的优先队列对象 pq ,数据元素为 int 类型。
priority_queue<int> pq;
2. priority_queue(const priority_queue&)
复制构造函数,用一个优先队列对象创建新的优先队列对象。例如,下面一行代码利用 priority_queue 对象 pq1 ,创建一个以双向链表为底层容器的 priority_queue 对象 pq2 。
// priority_queue<int, list<int> > pq1;
priority_queue<int, list<int> > pq2(pq1);
元素入队
优先队列容器的元素入队函数也是 push 函数,它调用堆算法函数将入队的元素移至队列堆中的正确位置,保证队列优先级高的元素始终位于队首。优先队列也不预设固定的大小,因此 push 函数不判断队列空间是否已满,都将元素放入队列。push 函数不会返回元素入队是否成功的信息。
void push(const value_type& x)
元素出对
优先队列容器的元素出对函数为 pop 函数,将优先级最高的元素删掉。该函数不判断队列是否已为空,都试图将队首元素删除。一般要先判断队列不为空,才进行元素出对操作。
取队首元素
优先队列容器的 top 函数,可用来读取队首元素,即优先级最高的元素。这个函数实际是调用了底层容器的 front 函数。需要注意的是,优先队列容器并不提供获取队尾元素的函数。如下是 top 函数的使用原型。
const value_type& top() const
队列非空判断
优先队列的操作基本都要使用 empty 函数,判断入队和出对的优先队列是否为空,再作下一步的操作。如下是 empty 函数的使用原型。
bool empty()
#include <iostream> #include <queue> using namespace std; void test_empty() { priority_queue<int> mypq; int sum (0); for (int i=1;i<=100;i++) mypq.push(i); while (!mypq.empty()) { sum += mypq.top(); mypq.pop(); } cout << "total: " << sum << endl; }//total: 5050 void test_pop() { priority_queue<int> mypq; mypq.push(30); mypq.push(100); mypq.push(25); mypq.push(40); cout << "Popping out elements..."; while (!mypq.empty()) { cout << " " << mypq.top(); mypq.pop(); } cout << endl; }//Popping out elements... 100 40 30 25 void test_top() { priority_queue<string> mypq; mypq.push("how"); mypq.push("are"); mypq.push("you"); cout << "mypq.top() is now:--->>> " << mypq.top() << endl; }//mypq.top() is now:--->>> you int main() { test_empty(); cout<<"\n***********************************************\n"; test_pop(); cout<<"\n***********************************************\n"; test_top(); cout<<"\n***********************************************\n"; priority_queue<float> q; // insert three elements into the priority queue q.push(66.6); q.push(22.2); q.push(44.4); // read and print two elements cout << q.top() << ' '; q.pop(); cout << q.top() << endl; q.pop(); // insert three more elements q.push(11.1); q.push(55.5); q.push(33.3); // skip one element q.pop(); // pop and print remaining elements while (!q.empty()) { cout << q.top() << ' '; q.pop(); } cout << endl; } /****************** 运行结果: total: 5050 *********************************************** Popping out elements... 100 40 30 25 *********************************************** mypq.top() is now:--->>> you *********************************************** 66.6 44.4 33.3 22.2 11.1 Process returned 0 (0x0) execution time : 0.055 s Press any key to continue. ********************/