优先级队列用法详解(priority_queue)
由于优先级队列的内部数据结构为 堆,所以这里先介绍堆的一些操作。
堆的一些函数操作在algorithm头文件中
//在[first, last)范围内构造最大堆,first,last 可以是vector指针也可以是数组指针
make_heap(first ,last)
make_heap(first ,last, cmpObject)
默认情况下是建立最大堆,即首元素为两个地址间的最大值。默认为less<int>,可以改为greater<int>即为建立最小堆
pop_heap(first ,last)
pop_heap(first ,last, cmpObject)
将front(即第一个最大元素)移动到end的前部,同时将剩下的元素重新构造成(堆排序)一个新的heap。
push_heap(first ,last)
push_heap(first ,last, cmpObject)
对刚插入的(尾部)元素做堆排序。在进行push_heap操作之前,除了最后一个元素以外的其他元素必须构成一个最大堆,
否则会报错。
sort_heap(first ,last)
sort_heap(first ,last, cmpObject)
将一个堆做排序,最终成为一个有序的系列,可以看到sort_heap时,必须先是一个堆(两个特性:1、最大元素在第一个 2、添加或者删除元素以对数时间),因此必须先做一次make_heap.
先写一个用 STL 里面堆算法实现的与真正的STL里面的priority_queue 用法相
似的 priority_queue,以加深对priority_queue 的理解
#include <iostream>
#include <algorithm>
#include <vector> using namespace std; class priority_queue
{
private:
vector<int> data;
public:
void push( int t ){
data.push_back(t);
push_heap( data.begin(), data.end());
}
void pop(){
pop_heap( data.begin(), data.end() );
data.pop_back();
}
int top() { return data.front(); }
int size() { return data.size(); }
bool empty() { return data.empty(); }
}; int main()
{
priority_queue test;
test.push( );
test.push( );
test.push( );
test.push( );
test.push();
test.push();
while( !test.empty() ){
cout << test.top() << endl;
test.pop(); }
return ;
}
模板声明带有三个参数,priority_queue<Type, Container, Functional>
Type 为数据类型, Container 为保存数据的容器, Functional 为元素比较方式。
Container 必须是用数组实现的容器,比如 vector, deque 但不能用list.
STL里面默认用的是vector. 比较方式默认用operator< , 所以如果你把后面俩个
参数 缺省的话,优先队列就是大顶堆,队头元素最大。
下面的程序为建立一个最小堆的例子 priority_queue<int,vector<int>,greater<int>> q;
#include <iostream>
#include <queue> using namespace std; int main(){
priority_queue<int, vector<int>, greater<int> > q;
for( int i= ; i< ; ++i ) q.push( rand() );
while( !q.empty() ){
cout << q.top() << endl;
q.pop();
}
getchar();
return ;
}
自定义类型Node的优先级队列,重载比较运算符'<':
#include <iostream>
#include <queue> using namespace std; struct Node{
int x, y;
Node( int a= , int b= ):
x(a), y(b) {}
}; 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> q;
for( int i= ; i< ; ++i )
q.push( Node( rand(), rand() ) );
while( !q.empty() ){
cout << q.top().x << ' ' << q.top().y << endl;
q.pop();
}
getchar();
return ;
}
重载‘<’之后可以只带一个模板参数定义优先级队列对象,但不能声明priority_queue<Node, vector<Node>, greater<Node> >
这种类型,原因是greater<Node>没有定义,要想定义上述形式必须定义一个比较的类cmp,具体实现如下代码。
#include <iostream>
#include <queue> using namespace std; struct Node{
int x, y;
Node( int a= , int b= ):
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> q;
for( int i= ; i< ; ++i )
q.push( Node( rand(), rand() ) );
while( !q.empty() ){
cout << q.top().x << ' ' << q.top().y << endl;
q.pop();
}
getchar();
return ;
}
参考博文:
http://blog.163.com/zjut_nizhenyang/blog/static/1695700292010101632059540/
http://blog.csdn.net/fuyufjh/article/details/47144869
http://blog.sina.com.cn/s/blog_959bf1d3010191h1.html
优先级队列用法详解(priority_queue)的更多相关文章
- STL priority_queue 常见用法详解
<算法笔记>学习笔记 priority_queue 常见用法详解 //priority_queue又称优先队列,其底层时用堆来实现的. //在优先队列中,队首元素一定是当前队列中优先级最高 ...
- Vue1.0用法详解
Vue.js 不支持 IE8 及其以下版本,因为 Vue.js 使用了 IE8 不能实现的 ECMAScript 5 特性. 开发环境部署 可参考使用 vue+webpack. 基本用法 1 2 3 ...
- c++中vector的用法详解
c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间 ...
- JS逗号运算符的用法详解
逗号运算符的用法详解 注意: 一.由于目前正在功读JavaScript技术,所以这里拿JavaScript为例.你可以自己在PHP中试试. 二.JavaScript语法比较复杂,因此拿JavaScri ...
- 教程-Delphi中Spcomm使用属性及用法详解
Delphi中Spcomm使用属性及用法详解 Delphi是一种具有 功能强大.简便易用和代码执行速度快等优点的可视化快速应用开发工具,它在构架企业信息系统方面发挥着越来越重要的作用,许多程序员愿意选 ...
- oracle正则表达式regexp_like的用法详解
oracle正则表达式regexp_like的用法详解 /*ORACLE中的支持正则表达式的函数主要有下面四个:1,REGEXP_LIKE :与LIKE的功能相似2,REGEXP_INSTR :与IN ...
- lsof 命令用法详解
lsof 命令用法详解 作用 用于查看你进程开打的文件,打开文件的进程,进程打开的端口(TCP.UDP).找回/恢复删除的文件.是十分方便的系统监视工具,因为lsof命令需要访问核心内存和各种文件,所 ...
- golang格式化输出-fmt包用法详解
golang格式化输出-fmt包用法详解 注意:我在这里给出golang查询关于包的使用的地址:https://godoc.org 声明: 此片文章并非原创,大多数内容都是来自:https:// ...
- Elasticsearch SQL用法详解
Elasticsearch SQL用法详解 mp.weixin.qq.com 本文详细介绍了不同版本中Elasticsearch SQL的使用方法,总结了实际中常用的方法和操作,并给出了几个具体例子 ...
随机推荐
- python实现汉诺塔移动
汉诺塔问题 汉诺塔是根据一个传说形成的一个问题.汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大 ...
- Luogu P1092 虫食算
题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中# ...
- PHP开发丨3个简单的方法处理emoji表情
一般Mysql表设计时,都是用UTF8字符集的.把带有emoji的昵称字段往里面insert一下就没了,整个字段变成了空字符串.这是怎么回事呢?原来是因为Mysql的utf8字符集是3字节的,而emo ...
- VxWorks镜像简介
VxWorks镜像可分为三类: 可加载型VxWorks镜像:存储在开发机上,运行在板上RAM中 基于ROM的VxWorks镜像:存储在板上ROM,运行在板上RAM中 ROM驻留的VxWor ...
- freemarker报错之一
freemarker 1.错误描述 java.io.FileNotFoundException: Template user.ftl not found. at freemarker.template ...
- Exynos4412交叉编译环境搭建
Exynos4412交叉编译环境搭建 交叉编译:在PC机(x86平台)上开发程序,在ARM板上运行,提高开发.编译速度. 环境: Tiny4412SDK1506开发板 需要软件: arm-linux- ...
- 芝麻HTTP:批量部署Splash负载集群
安装Ansible: 看官方文档去:http://www.ansible.com.cn/index.html 好像这个主控端不支持Windows? 大家虚拟机装个Ubuntu吧. 闲话少扯直接上干货: ...
- WPF基础篇之命名空间
WPF中XAML与C#一样,也有自己独立的编译器.XAML会被解析和编译,最终形成微软的中间语言存储在程序集中.在解析和编译XAML的语言过程中,我们经常需要告诉编译器一些重要的信息,比如XAML代码 ...
- 主流nosql数据库对比
目前开源的NOSQL数据库有,Redis,Tokyo Cabinet,Cassandra,Voldemort,MongoDB,Dynomite,HBase,CouchDB,Hypertable, Ri ...
- 用VSCode开发一个asp.net core2.0+angular5项目(5): Angular5+asp.net core 2.0 web api文件上传
第一部分: http://www.cnblogs.com/cgzl/p/8478993.html 第二部分: http://www.cnblogs.com/cgzl/p/8481825.html 第三 ...