文章目录

  • priority_queue
    • 一.优先队列简介
    • 二.优先队列特性和操作
      • 1.头文件&定义
      • 2.默认优先输出大数据
      • (1).举例
      • 3.优先输出小数据 即小顶堆
      • (1).举例
      • 4.自定义优先级 重载默认的 < 符号
        • (1).使用 funtion .
        • (2). 自定义数据类型
    • 三.基本函数实现
      • 1.构造函数
      • 2.添加函数
      • 3.删除函数
      • 4.判断函数
      • 5.大小函数
      • 6.其他函数
      • 7.总结
  • 代码详解
    • 1.基本类型优先队列的例子:
    • 2.用pair做优先队列元素的例子:
    • 3.用自定义类型做优先队列元素的例子

priority_queue

优先队列(priority_queue),实际上,它的本质就是一个heap,可以参考传送门
这个写的也不错

优先级队列是一个拥有权值观念的queue。它允许在底端添加元素、在顶端去除元素、删除元素。 缺省情况下,优先级队列利用一个大顶堆完成。


而C++STL中的优先队列就是在这个队列的基础上,把其中的元素加以排序。其内部实现是一个二叉堆。所以优先队列其实就是把堆模板化,将所有入队的元素排成具有单调性的一队,方便我们调用。

一.优先队列简介

普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。
在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest
out)的行为特征。
首先要包含头文件#include, 他和queue不同的就在于我们可以自定义其中数据的优先级,让优先级高的排在队列前面,优先出队。

二.优先队列特性和操作

优先队列具有队列的所有特性,包括队列的基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的。

1.头文件&定义

#include <queue>
#include <functional> //greater<>// 定义
priority_queue<int> pq;

2.默认优先输出大数据

  • priority_queue<Type, Container, Functional>

  • 其中, Type 为数据类型. Container 为保存数据的容器. Functional 为元素比较的方式.

  • 若不写后面两个参数.

容器 默认使用 vector

比较方式 默认使用 operator < 即优先队列是大顶堆. 队头元素最大
大根堆声明方式:
大根堆就是把大的元素放在堆顶的堆。优先队列默认实现的就是大根堆,所以大根堆的声明不需要任何花花肠子,直接按C++STL的声明规则声明即可。

#include<queue>
priority_queue<int> q;
priority_queue<string> q;
priority_queue<pair<int,int> > q;

C++中的int,string等类型可以直接比较大小,所以不用我们多操心,优先队列自然会帮我们实现。但是如果是我们自己定义的结构体,就需要进行重载运算符了

(1).举例

srand(time(NULL));
priority_queue<int> pq1; // 默认是最大堆...
std::cout << "start..." << endl;
for (int i = 0; i < 10; i++) {int t = rand() % 100;cout << t << ends;pq1.push(t);
}
std::cout << endl;
while (!pq1.empty())
{cout << pq1.top() << ends;pq1.pop();
}
cout << endl;

输出:

3.优先输出小数据 即小顶堆

  • priority_queue<int, vector<int>, greater<int> > p;
  • 使用 greater<int> . 即改用 operator >
    小根堆声明方式
    大根堆是把大的元素放堆顶,小根堆就是把小的元素放到堆顶。

实现小根堆有两种方式:

第一种是比较巧妙的,因为优先队列默认实现的是大根堆,所以我们可以把元素取反放进去,因为负数的绝对值越小越大,那么绝对值较小的元素就会被放在前面,我们在取出的时候再取个反,就瞒天过海地用大根堆实现了小根堆。

第二种:

小根堆有自己的声明方式,我们记住即可(我也说不明白道理):

priority_queue<int,vector<int>,greater<int> >q;

注意,当我们声明的时候碰到两个"<“或者”>"放在一起的时候,一定要记得在中间加一个空格。这样编译器才不会把两个连在一起的符号判断成位运算的左移/右移。

(1).举例

priority_queue<int, vector<int>, greater<int>> pq2; // 最小堆std::cout << "start..." << endl;
for (int i = 0; i < 10; i++) {int t = rand() % 100;std::cout << t << ends;pq2.push(t);
}
std::cout << endl;while (!pq2.empty())
{cout << pq2.top() << ends;pq2.pop();
}
cout << endl;

结果:

4.自定义优先级 重载默认的 < 符号

(1).使用 funtion .

// 定义比较函数
// 后面一个表示栈顶元素? 所以这个是 "最小堆"
bool myCom(int a, int b) {return a % 10 > b % 10;
}// 使用
priority_queue<int, vector<int>, function<bool(int,int)>> pq3(myCom); std::cout << "start..." << endl;
for (int i = 0; i < 10; i++) {int t = rand() % 100;std::cout << t << ends;pq3.push(t);
}std::cout << endl;while (!pq3.empty())
{cout << pq3.top() << ends;pq3.pop();
}
cout << endl;

输出结果:

(2). 自定义数据类型

#include<iostream>
#include<queue>
#include<cstdlib>
using namespace std;
struct Node{int x,y;Node(int a=0, int b=0):x(a), y(b) {}
};struct cmp{bool operator()(Node a, Node b){if(a.x == b.x)  return a.y>b.y;return a.x>b.x;}
};int main(){priority_queue<Node, vector<Node>, cmp>p;for(int i=0; i<10; ++i)p.push(Node(rand(), rand()));while(!p.empty()){cout<<p.top().x<<' '<<p.top().y<<endl;p.pop();}//while//getchar();return 0;

三.基本函数实现

首先函数在头文件中,归属于命名空间std,使用的时候需要注意。

priority_queue<int> q1;
priority_queue< pair<int, int> > q2;  // 注意在两个尖括号之间 一定要留空格。
priority_queue<int, vector<int>, greater<int> > q3; // 定义小的先出队

1.构造函数

1.普通方法

priority_queue<int> q;               
//通过操作,按照元素从大到小的顺序出队
priority_queue<int,vector<int>, greater<int> > q;    
//通过操作,按照元素从小到大的顺序出队

2、自定义优先级:

struct cmp {     operator bool ()(int x, int y)     {        return x > y;   // x小的优先级高       //也可以写成其他方式,//如: return p[x] > p[y];表示p[i]小的优先级高}
};

priority_queue<int, vector, cmp> q; //定义方法
//其中,第二个参数为容器类型。第三个参数为比较函数。
3、结构体声明方式:

struct node {     int x, y;     friend bool operator < (node a, node b)     {         return a.x > b.x;    //结构体中,x小的优先级高     }
};

priority_queue<node>q; //定义方法
//在该结构中,y为值, x为优先级。
//通过自定义operator<操作符来比较元素中的优先级。
//在重载”<”时,最好不要重载”>”,可能会发生编译错误

2.添加函数

  • q.push();插入元素到队尾 (并排序)
  • q.emplace(); 原地构造一个元素并插入队列

3.删除函数

  • q.pop();弹出队头元素

4.判断函数

  • q.empty();队列是否为空

5.大小函数

  • q.size() 返回队列内元素个数

6.其他函数

  • q.top() ;访问队头元素,返回队列首元素,不改变队列
  • swap 交换内容

7.总结

top 访问队头元素
empty 队列是否为空
size 返回队列内元素个数
push 插入元素到队尾 (并排序)
emplace 原地构造一个元素并插入队列
pop 弹出队头元素
swap 交换内容

用法 作用
q.top() 返回priority_queue的首元素
q.push() 向priority_queue中加入一个元素
q.size() 返回priority_queue当前的长度(大小)
q.pop() 从priority_queue队头删除一个元素
q.empty() 返回priority_queue是否为空,1为空、0不为空

注意:priority_queue取出队首元素是使用top,而不是front,这点一定要注意!!

代码详解

1.基本类型优先队列的例子:

#include<iostream>
#include <queue>
using namespace std;
int main()
{//对于基础类型 默认是大顶堆priority_queue<int> a; //等同于 priority_queue<int, vector<int>, less<int> > a;//   这里一定要有空格,不然成了右移运算符↓↓priority_queue<int, vector<int>, greater<int> > c; //这样就是小顶堆priority_queue<string> b;for (int i = 0; i < 5; i++) {a.push(i);c.push(i);}while (!a.empty()) {cout << a.top() << ' ';a.pop();} cout << endl;while (!c.empty()) {cout << c.top() << ' ';c.pop();}cout << endl;b.push("abc");b.push("abcd");b.push("cbd");while (!b.empty()) {cout << b.top() << ' ';b.pop();} cout << endl;return 0;
}

运行结果:
4 3 2 1 0
0 1 2 3 4
cbd abcd abc
请按任意键继续. . .

2.用pair做优先队列元素的例子:

规则:pair的比较,先比较第一个元素,第一个相等比较第二个。

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int main()
{priority_queue<pair<int, int> > a;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 (!a.empty()) {cout << a.top().first << ' ' << a.top().second << '\n';a.pop();}
}

运行结果:
2 5
1 3
1 2
请按任意键继续. . .

3.用自定义类型做优先队列元素的例子

#include <iostream>
#include <queue>
using namespace std;//方法1
struct tmp1 //运算符重载<
{int x;tmp1(int a) {x = a;}bool operator<(const tmp1& a) const{return x < a.x; //大顶堆}
};//方法2
struct tmp2 //重写仿函数
{bool operator() (tmp1 a, tmp1 b) {return a.x < b.x; //大顶堆}
};int main()
{tmp1 a(1);tmp1 b(2);tmp1 c(3);priority_queue<tmp1> d;d.push(b);d.push(c);d.push(a);while (!d.empty()) {cout << d.top().x << '\n';d.pop();}cout << endl;priority_queue<tmp1, vector<tmp1>, tmp2> f;f.push(b);f.push(c);f.push(a);while (!f.empty()) {cout << f.top().x << '\n';f.pop();}
}

运行结果:

3
2
1

3
2
1
请按任意键继续. . .

优先队列(priority_queue)总结相关推荐

  1. C++ STL中的优先队列(priority_queue)使用

    原文:https://www.cnblogs.com/cielosun/p/5654595.html 今天讲一讲优先队列(priority_queue),实际上,它的本质就是一个heap,我从STL中 ...

  2. 优先队列priority_queue 用法详解

    优先队列priority_queue 用法详解 优先队列是队列的一种,不过它可以按照自定义的一种方式(数据的优先级)来对队列中的数据进行动态的排序 每次的push和pop操作,队列都会动态的调整,以达 ...

  3. 浅谈C++ STL中的优先队列(priority_queue)

    2019独角兽企业重金招聘Python工程师标准>>> 从我以前的博文能看出来,我是一个队列爱好者,很多并不是一定需要用队列实现的算法我也会采用队列实现,主要是由于队列和人的直觉思维 ...

  4. ZOJ 2849 Attack of Panda Virus (优先队列 priority_queue)

    优先队列,据说标程是并查集,没思路.貌似优先队列都是直接用stl写的,又逼我用stl了.prioriry_queue不熟. ps: value值越小,优先级越高.所以重载 < 运算符时按优先级从 ...

  5. 9.优先队列,priority_queue

    1 #include <iostream> 2 #include <queue> 3 #include <deque> 4 #include <list> ...

  6. 优先队列(priority_queue)的原理及用法

    一.优先队列的原理及使用 std::priority_queue:在优先队列中,优先级高的元素先出队列,并非按照先进先出的要求,类似一个堆(heap).其模板声明带有三个参数,priority_que ...

  7. c++——优先队列(priority_queue)

    优先队列详解/C++ 优先队列 1.概念:什么是优先队列呢?在优先队列中,元素被赋予优先级,当访问元素时,具有最高级优先级的元素先被访问 .即优先队列具有最高级先出的行为特征.它可以说是队列和排序的完 ...

  8. POJ 1581 优先队列 priority_queue -- 比赛胜者求解

    题目链接:http://poj.org/problem?id=1581 题目大意: 给定选手姓名,及答题提交次数(提交正确前,错误一次罚20分),每题的做题时间罚分(未正确作答的不罚分),最后求谁是胜 ...

  9. 优先队列priority_queue自定义比较函数

    以一个例子进行说明,假设优先队列的每个元素是pair<int,int>,我需要自定义一个用于pair<int,int>比较的函数: decltype返回该变量的类型 bool ...

  10. 【转】c++优先队列(priority_queue)用法详解

    既然是队列那么先要包含头文件#include <queue>, 他和queue不同的就在于我们可以自定义其中数据的优先级, 让优先级高的排在队列前面,优先出队 优先队列具有队列的所有特性, ...

最新文章

  1. python快速编程入门课后简答题答案-编程python入门 编程python入门课后习题
  2. android+4.4.2+横屏,Android 横竖屏和布局问题
  3. 读《数学之美》第四章 谈谈分词
  4. 体积最小桌面linux,Tiny Core Linux - 体积最小的精简 Linux 操作系统发行版之一 (仅10多MB)...
  5. Windows破解逆向-CrackMe_1实例(使用IDA Pro修改静态区资源)
  6. wordpress黑镜2.0作品图片素材类网站模板
  7. 【python工具篇】pip和pypi
  8. 201521123083《Java程序设计》第11周学习总结
  9. andriod创建用户界面(1)
  10. python 类的执行中保部存值_VisualFoxPro的报表文件.FRX中保存的是______。
  11. Rundll32.exe使用方法大全
  12. __wakeup绕过版本_PHP__wakeup()方法
  13. 自定义linux桌面,教您6个自定义Ubuntu桌面的步骤
  14. 烂笔头笔记:favicon配置不是所有浏览器都兼容
  15. 计算机动画可分为二维和三维动画,二维动画与三维动画设计的区分
  16. 12张图,二手房数据分析及可视化
  17. 【文章阅读】【超解像】--Residual Dense Network for Image Super-Resolution
  18. python语言入门自学-Python入门
  19. 【LeetCode】55. 跳跃游戏 (JavaScript)
  20. 用c语言构造真值表,构造命题公式的真值表--biaobiao88

热门文章

  1. 一位程序媛MM眼中的程序员???
  2. 评价好的良心浏览器,最后一个比360浏览器好用
  3. 内存测试软件 ddr4,DDR4内存芯片测试工具;DDR4内存检测仪
  4. Jeffrey Dean联署论文 The Case for Learned Index Structures
  5. python几个循环_python 几个循环的效率测试
  6. am335xSD卡启动--文件系统制作
  7. 千姿百态项目经理2——“缥缈”项目经理
  8. wlacm 铲雪车snow 题解
  9. 中英文金额大写转换器
  10. java大小写金额转换_java将金额转化为大写金额