【STL 堆 】
来源:互联网 发布:雷蛇键盘链接mac 编辑:程序博客网 时间:2024/05/02 01:38
一.heap
在STL中,priority_queue(优先权队列)的底层机制是最大堆,因此有必要先来了解一下heap。heap采用完全二叉树的结构,当然不是真正的binary tree,因为对于完全二叉树,我们通常用一个数组来表示。
以下几个算法都是STL的泛型算法,包含在头文件algorithm里,priority_queue的push(),pop()都有直接调用它们。
1.push_heap算法
首先,将新元素插入到底层vector的end()处。为了满足最大堆原理(每个结点的值必须大于或等于其子结点的值),于是将新结点与其父亲结点比较,如果其值大于父亲结点,就交换父子结点,直到不需要交换或者它已经到达根结点为止。
2.pop_heap算法
因为作为最大堆,根结点即为最大值。交换vector首尾(first和last)元素,并重新调整[first,last-1)部分,也就是将“新根结点”跟其较大子结点交换,并持续下放,知道叶子结点为止。注意,pop_heap之后,最大元素只是被放在底部容器的最尾端,并没有被取走。若要取走,可用vector的pop_back()函数。
3.sort_heap算法
持续对整个heap做pop_heap操作,每次将操作范围从后向前缩减一个元素,于是我们得到一个递增序列。显然,排序后的heap不是一个合法的heap了。
4.make_heap算法
这个算法用来将数组转化成一个heap
二,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) //堆排序
#include<cstdlib>#include<cstdio>#include<vector>#include<algorithm>using namespace std;int main(){ int a[9]={0,1,2,3,4,5,6,7,8,}; vector<int>ivec(a,a+9); make_heap(ivec.begin(),ivec.end()); for(int i=0;i<ivec.size();i++) printf("%d ",ivec[i]); printf("\n"); ivec.push_back(7); push_heap(ivec.begin(),ivec.end()); for(int i=0;i<ivec.size();i++) printf("%d ",ivec[i]); printf("\n"); pop_heap(ivec.begin(),ivec.end()); printf("%d\n",ivec.back()); ivec.pop_back(); for(int i=0;i<ivec.size();i++) printf("%d ",ivec[i]); printf("\n"); sort_heap(ivec.begin(),ivec.end()); for(int i=0;i<ivec.size();i++) printf("%d ",ivec[i]); printf("\n");}
三,priority_queue 实例
#include<queue>#include<algorithm>#include<cstdio>using namespace std;int main(){ int a[9]={1,2,4,3,6,5,9,8,7}; priority_queue<int>ipq(a,a+9); printf("size;%d\n",ipq.size()); for(int i=0;i<ipq.size();i++) printf("%d ",ipq.top()); printf("\n"); while(!ipq.empty()){ printf("%d ",ipq.top()); ipq.pop(); } printf("\n");}
1)STL里面默认用的是 vector. 比较方式默认用 operator< , 所以如果你把后面俩个参数缺省的话,优先队列就是大顶堆,队头元素最大。如果要用到小顶堆,则一般要把模板的三个参数都带进去。STL里面定义了一个仿函数 greater<>,对于基本类型可以用这个仿函数声明小顶堆
#include <iostream>#include <queue>#include <cstdlib>#include<cstdio>using namespace std;int main(){ priority_queue<int, vector<int>, greater<int> > q; for( int i= 0; i< 10; ++i ) q.push(i); while( !q.empty() ){ printf("%d ",q.top()); q.pop(); } printf("\n"); return 0;}
2)5)自定义类型重载 operator< 后,声明对象时就可以只带一个模板参数。但此时不能像基本类型这样声明priority_queue<Node, vector<Node>, greater<Node> >;原因是 greater<Node> 没有定义,如果想用这种方法定义则可以按如下方式:
- STL -- 堆
- 【STL 堆 】
- STL堆
- 【STL】堆
- STL的堆操作
- poj3253【贪心+堆(STL)】
- STL 堆操作
- STL 堆操作 .
- stl中的堆操作
- STL 堆操作
- STL heap堆
- STL 之堆算法
- STL算法---堆算法
- STL之堆操作
- STL中的堆操作
- STL 堆(heap)
- STL之heap 堆
- STL 堆 heap
- android系统如何自适应屏幕大小
- 开始写博客啦l
- 算法java实现--动态规划--流水作业调度问题
- 食物链
- 删除在第二个字符串中出现的字符
- 【STL 堆 】
- java.lang.NoSuchMethodError: antlr.collections.AST.getLine()I 错误解决
- 外包模式下的精益敏捷开发 (人员能力篇)
- android的tween动画在动画结束后停止
- ubuntu 12.04 root自动登陆
- 创建线程后马上CloseHandle(threadhandle)起什么作用
- HDOJ 4612 Warm up
- java操作(DOM、SAX、JDOM、DOM4J)xml方式的四种比较与详解
- 猜拳小游戏