参考博文:https://blog.csdn.net/weixin_36888577/article/details/79937886
最近做到一些使用堆排序的题,因此总结一下priority_queue
优先队列也是队列,因此头文件为,与queue的不同在于可以定义数据的优先级,在插入数据时会自动排序。
基本操作
- top 访问队头元素
- push 插入元素到队尾并排序
- pop 弹出队头元素
- empty
- size
- emplace 原地构造一个元素并插入队列
- swap
定义
priority_queue<type,container,functional>
- type 元素的数据类型
- container 必须是用数组实现的容器,比如vector,deque。默认为vector
- functional 优先级的比较方法。对于内置类型默认为less(大顶堆)
- 对于内置类型构成的,使用默认比较方式的优先队列,只需要指定type即可
- 具有所有队列的特性,只是添加了自动排序。实际用堆来实现
std::string wrds [] {"one", "two", "three", "four"};
std::priority_queue<std::string, std::vector<std::string>, std::greater<std::string>> words(std::begin(wrds), std::end(wrds));
可以用任何容器的迭代器(开始和结束)来初始化优先队列。这里使用operator>()对元素对象进行比较,从而排序。
std::vector<int> values{21, 22, 12, 3, 24, 54, 56};
std::priority_queue<int> numbers(std::less<int>(),values);
//使用大括号也可以
std::priority_queue<int> numbers{std::less<int>(),values};
//模板指定了比较方式,构造函数的第一个参数也必须传入
std::priority_queue<std::string, std::vector<std::string>, std::greater<std::string>> words(std::greater<std::string>(),w);
- 用vector或者deque容器来初始化priority_queue
- 构造函数的第一个参数为比较函数,第二个参数为容器。要注意的是,即使模板中已经指定了比较方式,第一个参数也必不可少。
迭代器
priority_queue没有迭代器。只能用top和pop依次取出元素来遍历。且如此遍历会将队列清空。
内置类型举例
//升序队列 (小顶堆)
priority_queue <int,vector<int>,greater<int> > q1;
//降序队列 (大顶堆)
priority_queue <int,vector<int>,less<int> > q2;
元素类型为pair
- 当需求为按元素出现的频率排序,在构建了记录出现次数的哈希表以后,希望对出现的次数进行排序,并保持对应关系。此处用priority_queue<pair<T1,T2> >来实现再合适不过
- 比较规则为:先对first进行比较,若first相等,则比较second
priority_queue<pair<int, int> > q3;
pair<int, int> b(1, 2);
pair<int, int> c(1, 3);
pair<int, int> d(2, 5);
a.push(d);
a.push(c);
a.push(b);
while (!q3.empty())
{
cout << q3.top().first << " " << q3.top().second << endl;
q3.pop();
}
自定义类型
类内运算符重载
struct test1
{
int x;
test1(int a) {x = a;}
bool operator<(const test1& a) const
{
return x < a.x; //大顶堆 less
}
};
int main() {
test1 a(1);
test1 b(2);
test1 c(3);
priority_queue<test1> test_pq;
test_pq.push(a);
test_pq.push(b);
test_pq.push(c);
while (!test_pq.empty()) {
std::cout<<test_pq.top().x<<std::endl;
test_pq.pop();
}
system("pause");
}
//输出 3 2 1
类外运算符重载
struct test1
{
int x;
test1(int a) {x = a;}
};
bool operator<(const test1& a,const test1& b)
{
return a.x < b.x; //大顶堆 less
}
重写仿函数
struct test1
{
int x;
test1(int a) {x = a;}
};
struct func
{
bool operator()(const test1& a,const test1& b)
{
return a.x < b.x; //大顶堆
}
};
int main() {
test1 a(1);
test1 b(2);
test1 c(3);
priority_queue<test1, vector<test1>, func> test_pq; //写pq模板时调用仿函数
test_pq.push(a);
test_pq.push(b);
test_pq.push(c);
while (!test_pq.empty()) {
std::cout<<test_pq.top().x<<std::endl;
test_pq.pop();
}
system("pause");
}