STL学习笔记-- priority_queue
priority_queue 优先队列容器
优先队列容器也是一种从一端入队,另一端出对的队列。不同于一般队列的是,队列中最大的元素总是位于队首位置,因此,元素的出对并非按照先进先出的要求,将最先入队的元素出对,而是将当前队列中的最大元素出对。
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()
1 ----------------------------------------- 按优先级分别获取优先队列的所有元素 2 #include <queue> 3 #include <iostream> 4 using namespace std; 5 int main() 6 { 7 priority_queue<int> pq; 8 pq.push(7); 9 pq.push(19); 10 pq.push(33); 11 pq.push(26); 12 pq.push(29); 13 // 按优先级大小读取队列元素 14 while (!pq.empty()) 15 { 16 // 打印出 33 29 26 19 7 17 cout << pq.top() << ' '; 18 pq.pop(); 19 } 20 cout << endl; 21 22 return 0; 23 }
1 /* 队列的大小 2 优先队列的元素个数可用 size 函数获取。如果每次元素入队前,都先检查当前队列的元素个数,以此判断是否再允许元素入队,那么就可实现一个具有固定大小的优先队列。如下是 size 函数的使用原型 3 size_type size() 4 5 下面的示例程序将优先队列设为 50 个 int 元素大小,并使用具有数组操作符 "[]" 的双端队列 deque 作底层结构,每当元素入队时,都调用 size 函数检查是否会超过限定的长队界限,实现出一个固定大小的优先队列。 6 */ 7 8 ------------------------------------------ 固定大小的优先队列 9 #include <queue> 10 #include <iostream> 11 #define QUEUE_SIZE 50 12 using namespace std; 13 int main() 14 { 15 priority_queue<int, deque<int> > pq; 16 if (pq.size() < QUEUE_SIZE) 17 pq.push(36); 18 if (pq.size() < QUEUE_SIZE) 19 pq.push(51); 20 if (pq.size() < QUEUE_SIZE) 21 pq.push(12); 22 if (pq.size() < QUEUE_SIZE) 23 pq.push(361); 24 // 元素出对 25 while (!pq.empty()) 26 { 27 // 打印 361 51 36 12 28 cout << pq.top() << ' '; 29 pq.pop(); 30 } 31 cout << endl; 32 33 return 0; 34 }
--------------------- priority_queue 小结
priority_queue 优先队列是一种应用相当广泛的数据结构,元素入队后按优先级进行出对,操作系统和一些应用程序的任务调度处理都使用了优先队列来实现。C++ STL 提供的 priority_queue 容器对优先队列的数据结构和受限操作进行了泛化封装,包括队列初始化、元素入队、取队首元素(优先级最高的元素)、元素出对、队列是否为空以及获取当前队列长度等操作。
不同于 queue 队列,priority_queue 优先队列默认使用 vector 作底层架构,获取队首元素的函数为 top 函数,不提供获取队尾的函数。同样地,通过检查当前优先队列长度,可决定是否允许元素入队,以此实现具有固定长度的优先队列。