装载自http://blog.csdn.net/tianshuai1111/article/details/7652553

一,概述

priority_queue是拥有权值观念的queue,它允许加入新元素,移除旧元素。调用 STL里面的 make_heap(), pop_heap(), push_heap() 算法实现,也算是堆的另外一种形式。但它是一个queue所以只允许在底端加入元素,在顶端移除元素。

排序:按照权值大小顺序排序,而不是按照push 进去的顺序排序。权值高者排在前面,权值低者排在后面。

允许以任何大小顺序插入到优先队列,但取出时是按照权值大小取。

二,heap(堆)简介

1)采用vector存储,是一颗完全二叉树(complete binary tree)的形式。

heap分为 max_heap 和 min_heap,前者最大权值在根,后者最小权值在根。

2)建立堆过程

vector中元素先调整为堆的形式。

插入元素时,将元素放到vector 的最后面end(),然后上溯调整堆。

3)heap算法      // #include <algorithm>

make_heap(first,last)       //初建堆

push_heap(first,last)        //插入元素,并调整为堆

pop_heap(first,last)         //弹出元素,并调整为堆

sort_heap(first,last)         //堆排序

4)示例

 #include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm> using namespace std; int main(int argc, char** argv) { int ia[]={,,,,,,,,};
vector<int> ivec(ia,ia+); make_heap(ivec.begin(),ivec.end()); //#include <algorithm>
for(int i=;i<ivec.size();++i)
cout<<ivec[i]<<" ";
cout<<endl; ivec.push_back();
push_heap(ivec.begin(),ivec.end());
for(int i=;i<ivec.size();++i)
cout<<ivec[i]<<" ";
cout<<endl; pop_heap(ivec.begin(),ivec.end());
cout<<ivec.back()<<endl; //返回刚刚弹出的堆顶
ivec.pop_back(); //将最后一个元素弹出数组 for(int i=;i<ivec.size();++i)
cout<<ivec[i]<<" ";
cout<<endl; sort_heap(ivec.begin(),ivec.end());
for(int i=;i<ivec.size();++i)
cout<<ivec[i]<<" ";
cout<<endl; return ;
}

三,priority_queue 实例

 #include <queue>
#include <algorithm>
#include <iostream>
using namespace std; int main(int argc, char** argv) { int ia[]={,,,,,,,,};
priority_queue<int> ipq(ia,ia+);
cout<<"size:"<<ipq.size()<<endl; for(int i=;i<ipq.size();++i)
cout<<ipq.top()<<" ";
cout<<endl; while(!ipq.empty())
{
cout<<ipq.top()<<" ";
ipq.pop();
} return ;
}

2)自己实现priority_queue

STL里面的 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());//将动态数组vector中元素 建立成堆
}
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( ); while( !test.empty() ){
cout << test.top() << endl;
test.pop(); } return ; }

3)STL里面默认用的是 vector. 比较方式默认用 operator< , 所以如果你把后面俩个参数缺省的话,优先队列就是大顶堆,队头元素最大。如果要用到小顶堆,则一般要把模板的三个参数都带进去。STL里面定义了一个仿函数 greater<>,对于基本类型可以用这个仿函数声明小顶堆

 #include <iostream>
#include <queue>
#include <cstdlib> 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();
} return ;
}

4)对于自定义类型,则必须自己重载 operator< 或者自己写仿函数

 #include <iostream>
#include <queue>
#include <cstdlib> 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;
else
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();
} return ;
}

5)自定义类型重载 operator< 后,声明对象时就可以只带一个模板参数。但此时不能像基本类型这样声明priority_queue<Node, vector<Node>, greater<Node> >;原因是 greater<Node> 没有定义,如果想用这种方法定义则可以按如下方式:

 #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 ;
}

要注意的是,如果重载cmp,return a > b的形式形成的堆堆顶为最小元素!!

(转)【C++ STL】细数C++ STL 的那些事 -- priority_queue(优先队列)的更多相关文章

  1. 泛型编程、STL的概念、STL模板思想及其六大组件的关系,以及泛型编程(GP)、STL、面向对象编程(OOP)、C++之间的关系

    2013-08-11 10:46:39 介绍STL模板的书,有两本比较经典: 一本是<Generic Programming and the STL>,中文翻译为<泛型编程与STL& ...

  2. 细数iOS上的那些安全防护

    细数iOS上的那些安全防护  龙磊,黑雪,蒸米 @阿里巴巴移动安全 0x00 序 随着苹果对iOS系统多年的研发,iOS上的安全防护机制也是越来越多,越来越复杂.这对于刚接触iOS安全的研究人员来说非 ...

  3. 细数.NET 中那些ORM框架 —— 谈谈这些天的收获之一

    细数.NET 中那些ORM框架 —— 谈谈这些天的收获之一(转) ADO.NET Entity Framework        ADO.NET Entity Framework 是微软以 ADO.N ...

  4. 细数Qt开发的各种坑(欢迎围观)

    1:Qt的版本多到你数都数不清,多到你开始怀疑人生.从4.6开始到5.8,从MSVC编译器到MINGW编译器,从32位到64位,从Windows到Linux到MAC.MSVC版本还必须安装对应的VS2 ...

  5. STL非变易算法 - STL算法

    欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/1394600460.html 原创:ST ...

  6. 迄今最安全的MySQL?细数5.7那些惊艳与鸡肋的新特性(上)【转载】

    转自: DBAplus社群 http://www.toutiao.com/m5762164771/ 迄今最安全的MySQL?细数5.7那些惊艳与鸡肋的新特性(上) - 今日头条(TouTiao.com ...

  7. 细数Python Flask微信公众号开发中遇到的那些坑

    最近两三个月的时间,断断续续边学边做完成了一个微信公众号页面的开发工作.这是一个快递系统,主要功能有用户管理.寄收件地址管理.用户下单,订单管理,订单查询及一些宣传页面等.本文主要细数下开发过程中遇到 ...

  8. 细数AutoLayout以来UIView和UIViewController新增的相关API

    本文转载至 http://www.itjhwd.com/autolayout-uiview-uiviewcontroller-api/ 细数AutoLayout以来UIView和UIViewContr ...

  9. 细数MQ那些不得不说的8大好处

    消息队列(MQ)是目前系统架构中主流方式,在大型系统及大数据中广泛采用.对任何架构或应用来说, MQ都是一个至关重要的组件.今天我们就来细数MQ那些不得不说的好处. 好处一:解耦 在项目启动之初来预测 ...

随机推荐

  1. 安装SQL Server2008时 检测时有“重启计算机”失败

    第一种解决方案: 在学校的时候 遇到这种问题的解决办法是: 卸载VS,先安装SQL Server 2008 再安装VS 就行了: 第二种解决方案: 如果已经安装过VS,在安装SQL Server200 ...

  2. weChat聊天发送图片带有小尖角的实现

    weChat聊天发送图片带有小尖角的实现 1.#import <UIKit/UIKit.h>2.3.@interface JKShapeImage : UIView4.5.@propert ...

  3. Linux fork操作之后发生了什么?又会共享什么呢?

    今天我在阅读<Unix网络编程>时候遇到一个问题:accept返回时的connfd,是父子进程之间共享的?我当时很不理解,难道打开的文件描述符不是应该在父子进程间相互独立的吗?为什么是共享 ...

  4. SGU 163.Wise King

    一道题目长的水题.... 总结就一句话,给出n个(-3~3)的数,一个数m,取任意个数是使这些数的m次幂之和最大. code #include <iostream> #include &l ...

  5. 【POJ2985】【Treap + 并查集】The k-th Largest Group

    Description Newman likes playing with cats. He possesses lots of cats in his home. Because the numbe ...

  6. Queue学习

    Queue在Python中可以算作是一种容器,但是他和list,set,dict不一样. 1. Queue不是Python内置类型.它在Queue模块中定义. 2. 它不是iterator容器,他不能 ...

  7. 18 4Sum(寻找四个数之和为指定数的集合Medium)

    题目意思:给一个乱序数组,在里面寻找三个数之和为target的所有情况,这些情况不能重复,增序排列 思路:采用3Sum的做法 ps:有见一种用hash的,存任意两个元素的和,然后变成3sum问题,需要 ...

  8. Jquery 简单的Tab选项卡特效

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. emmet插件的导入与实用

    http://jingyan.baidu.com/article/ff4116259b057c12e48237b8.html http://www.iteye.com/news/27580 分享htm ...

  10. 转:使用 Docker 搭建 Java Web 运行环境

    原文来自于:http://www.codeceo.com/article/docker-java-web-runtime.html Docker 是 2014 年最为火爆的技术之一,几乎所有的程序员都 ...