大家好!本文会用C++模拟一个基本的priority_queue类,帮助我们更好的理解priority_queue的内置函数的实现与规则。
1. priority_queue介绍
priority_queue被叫做优先队列:
- 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。
- 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素),其数据结构类似于大堆。
- 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。
- 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:
- empty():检测容器是否为空
- size():返回容器中有效元素个数
- front():返回容器中第一个元素的引用
- push_back():在容器尾部插入元素
- pop_back():删除容器尾部元素
- 标准容器类vector和deque满足这些需求。默认情况下,如果没有为特定的priority_queue类实例化指定容器类,则使用vector。
- 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数make_heap、push_heap和pop_heap来自动完成此操作。
priority_queue数据结构:
2. priority_queue模拟实现
我们先来看看priority_queue需要实现哪些函数:
template <class T,class Container = vector<T>, class Compare = less<T>>
class priority_queue
{
public:
//构造函数
priority_queue() = default;
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last);
//容器操作
void adjust_up(int child);
void adjust_down(int parent);
bool empty() const;
size_t size() const;
const T& top() const;
void push(const T& x);
void pop();
private:
Container _c;
Compare comp;
};
}
priority_queue需要实现的函数很少,而且函数也多为复用 Container类型的内置函数,所以这里不多讲解,直接贴代码。(priority_queue的重点不在它的函数,在本篇的第三个专题)。
构造函数:
//强制编译器生成默认构造函数
priority_queue() = default;
//支持迭代器构造
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last)
{
while (first != last)
{
_c.push_back(*first);
first++;
};
for (int i = ((_c.size() - 1 - 1) / 2); i > 0; i--)
{
adjust_down(i);
};
};
容器操作函数:
//堆的向上调整函数
void adjust_up(int child