前言
此文让我们来认识学习priority_queue的知识
参考文档:https://legacy.cplusplus.com/reference/queue/priority_queue/
一、priority_queue构成
底层默认适配器使用的是vector默认生成的
优先级队列底层算法是使用的堆的算法生成的
构造:
主要接口
二、优先级队列使用
这里默认排序出大堆,想排序出小堆呢?
这里就要看priority_queue模板参数了
这里适配器默认给的是less
我们想要默认小堆就要是用greater(库里面有的)
(less和greater都是仿函数
)
注意:less是大堆greater是小堆
less:
greater:
三、仿函数
我们上面说到的less和greater都是仿函数。
什么是仿函数呢?(有些地方也叫函数对象)
我们这样定义这个类
- less定义:
2.less使用
仿函数的功能上主要是为了替代函数指针。
四、模拟实现
(包含对仿函数的使用)有注释解释
- priority_queue.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<vector>
namespace goat
{
priority_queue()
{}
//迭代器区间构造
template<class InputIterator>
priority_queue(InputIterator first,InputIterator last)
:_con(first,last)
{
//建堆
for (int i = (_con.size - 2) / 2; i >= 0; --i)
{
adjust_down(i);
}
}
//less和greater模拟实现
template<class T>
class Less//优先级队列中less和greater是为了比较大小
{
public:
bool operator()(const T& t1,const T& t2)
{
return t1 < t2;
}
};
template<class T>
class Greater
{
public:
bool operator()(const T& t1, const T& t2)
{
return t1 > t2;
}
};
//优先级队列模拟实现
template<class T, class Container = vector<T>,class Compare = Less<T> >//这里默认传Less这个仿函数
class priority_queue
{
public:
void adjust_up(size_t child)
{
size_t parent = (child - 1) / 2;
while (child > 0)
{
Compare com;
if(com(_con[parent] , _con[child]))
//if (_con[parent] < _con[child])当默认对象为less时这两个表达式是等价的
{
swap(_con[parent], _con[child]);
child = parent;
parent = (parent - 1) / 2;
}
else
{
break;
}
}
}
void adjust_down(size_t parent)
{
size_t child = parent * 2 + 1;
Compare com;
while (child < _con.size())
{
if (child + 1 < _con.size()
&& com(_con[child],_con[child + 1]))
++child;
//if(_con[parent] < _con[child])
if(com(_con[parent], _con[child]))
{
swap(_con[parent], _con[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void push(const T& x)
{
_con.push_back(x);
adjust_up(_con.size()-1);
}
void pop()
{
swap(_con[0], _con[_con.size()-1]);
_con.pop_back();
adjust_down(0);
}
const T& top()
{
return _con[0];
}
bool empty()
{
return _con.empty();
}
size_t size()
{
return _con.size();
}
private:
Container _con;
};
}
- test.cpp
void test_priority_queue3()
{
goat::priority_queue<int, vector<int>, goat::Less<int>> l;
goat::priority_queue<int, vector<int>, goat::Greater<int>> g;
//注意这里传的是类型
l.push(8);
l.push(0);
l.push(5);
l.push(12);
l.push(1);
g.push(8);
g.push(0);
g.push(5);
g.push(12);
g.push(1);
cout << "less大堆比较,构造堆" << endl;
while (!l.empty())
{
int i = l.top();
l.pop();
cout << i << " ";//大堆
}
cout << endl;
cout << "greater小堆比较,构造堆" << endl;
while (!g.empty())
{
int i = g.top();
g.pop();
cout << i << " ";//小堆
}
cout << endl;
}
int main()
{
test_priority_queue3();
return 0;
}
结果: