博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STL源码分析-heap部分
阅读量:7223 次
发布时间:2019-06-29

本文共 1454 字,大约阅读时间需要 4 分钟。

heap部分属于序列式容器一章

但是heap并不属于STL容器组件,其帮助于priority queue.

priority queue运行用户用任何次序将任何元素推入容器内,但取出时一定是从数值最高的元素开始取,binary max heap具有这样的特性,适合作为priority queue.底层机制。

若使用list作为priority queue底层机制,元素的插入操作可享常数时间,但是要找到list中的极值,要对整个list遍历。时间过长。

binary heap就是一种完全二叉树。也就是整颗树除了最底层的叶节点之外,是填满的,比如如下:

array表达式:ABCDEFGHIJ

由于完全二叉树 内没有任何节点漏洞,这带来一个极大的好处:可以利用array来存储所有节点。

也就是说某个节点位于array的i处时,左子节点位于2i处,右子节点位于2i+1处,父节点位于i/2处。通过这种简单的位置规则,array可以轻易实现出完全二叉树。这种利用array

表述tree的方式,成为隐式表述法

但array的缺点是无法动态改变大小,而heap却需要,因此用vector代替array是更好的选择

heap分为max-heap和min-heap两种,前者每个节点的键值大于等于其子节点键值,也就是从大到小排列,后者则是从小到大。因此max-heap的最大值在根节点,并总是位于底层vector的起头处。STL提供的是max-heap。因此只对max-heap进行分析。

heap算法

push_heap算法

功能:插入一个新元素

为了满足完全二叉树的条件,新加入的元素一定要放在最下一层作为叶节点,并填补在由左至右的第一个空格,也就是插入在vector的end()处。然后为了满足max-heap的条件,也就是每个节点大于等于其子节点的键值,执行一个上溯(percolate up)程序:将新节点与父节点比较,若比父节点大,就对换位置,如此一致上溯,知道不需对换或者根节点为止。

pop_heap算法

功能:将最大值取走

最大值必然在根节点,pop操作取走根节点(其实是摄至底部容器vector的尾端节点)后,为了满足完全二叉树,必须割舍最下层最右边的叶节点,并将其值重新安插至max-heap。

执行下溯程序:将空间节点与其较大子节点对调,并持续下放直到叶节点为止,然后将割舍的元素值设给这个已到达叶层的空洞节点,再执行一次上溯程序,即可。

sort_heap算法

功能:将heap排序,由小到大

既然每次pop_heap可获得heap键值最大的元素,如果持续对heap执行pop操作,能够得到一个递增序列。因为pop_heap会将最大元素放在最尾端。因此是递增序列。

注意:排序过后,原来的heap不是一个合法的heap了。

make_heap算法

功能:将现有的数据转化为一个heap,主要依据就是完全二叉树的隐式表述。

在实际程序中,要对一个vector(int) A进行排序,可以利用make_heap先将A转化为一个合法的heap,然后利用sort_heap将heap进行从小到大排序即可:

vector
A; make_heap(A.begin(), A.end());sort_heap(A.begin(), A.end());

转载于:https://www.cnblogs.com/sichenzhao/p/9320194.html

你可能感兴趣的文章
部署exchange2010三合一:之五:功能测试
查看>>
nginx编译安装参数
查看>>
代码托管
查看>>
第一次给ThinkPHP5核心框架提pull request的完整过程
查看>>
U-Mail邮件系统何以誉为信息整合中转枢纽
查看>>
强大的vim配置文件,让编程更随意
查看>>
崛起于Springboot2.X之配置文件详解(10)
查看>>
定时执行程序-Quartz简单实例
查看>>
【CF 应用开发大赛】MyfCMS系统
查看>>
windows下kangle虚拟主机-架设java空间的教程及心得
查看>>
Discuz! X2.5:文件目录结构
查看>>
我的友情链接
查看>>
TCP/IP协议及首部初了解
查看>>
防火墙iptables
查看>>
CUDA搭建
查看>>
memcached与PostgreSQL缓存命中机制
查看>>
百度地图路线检索(3)
查看>>
linux netstat 命令详解
查看>>
对前几篇blog的环境等的补充说明
查看>>
Curl命令使用解析大全
查看>>