STL源码剖析之heap,priority_queue【2013.11.25】

 STL源码剖析之heap,priority_queue【2013.11.25】

欢迎加入我们的QQ群,无论你是否工作,学生,只要有c / vc / c++ 编程经验,就来吧!158427611 【IT】C/C++/STL/Linux/W


priority_queue是一种特殊的 queuequeue的出队顺序是根据入队顺序确定的, priority_queue则有一种 权重概念,他的出队顺序由这个权重大小决定。

heap不是容器,但是却是实现priority_queue的关键,由他实现权重排列。实现权重出队


heap


heap在数据结构中,是一种堆的概念(二叉堆,这里分为大堆[max_heap]和小堆[min_heap],即最大值,最小值位于堆的跟节点,下图A)。

STL源码剖析之heap,priority_queue【2013.11.25】_第1张图片

对于堆的概念

所谓的大堆就是 父节点比子节点大,同样小堆就是父节点小于子节点。这样保持根节点永远是最大或最小的。

由于堆的特殊性质,完全二叉树,所以堆的数据可以用一个连续空间表示,其父子节点之间的关系可以是 A为第0个,其子节点A,B就是第 1 ,2个,即 2i和2i+1;


对于堆,在priority_queue中,最重要的就是heap的取出算法,即每次取最大或最小(pop);当然还有构造一个heap(push);

【1】构造heap就是一个一个节点push进heap;

第一个即为根节点,之后的push,则是和父节点比较,如果大就互换父子节点,再向上取父节点,循环。看图:

STL源码剖析之heap,priority_queue【2013.11.25】_第2张图片

代码如下:

STL源码剖析之heap,priority_queue【2013.11.25】_第3张图片STL源码剖析之heap,priority_queue【2013.11.25】_第4张图片

【2】取出堆POP,就是直接取跟节点,然后对应的互换子节点。保证堆的规范。

先取跟节点,然后判断两个子节点,大的子节点变成父节点;

然后并继续向下,左右子节点判断,取大的,并和堆的最后一个节点比较,如果最后一个大就把最后一个直接放到此节点,否则就是取大的子节点变父节点,继续向下重复操作

如图:

STL源码剖析之heap,priority_queue【2013.11.25】_第5张图片

代码如下:

STL源码剖析之heap,priority_queue【2013.11.25】_第6张图片STL源码剖析之heap,priority_queue【2013.11.25】_第7张图片STL源码剖析之heap,priority_queue【2013.11.25】_第8张图片

【1】heap在STL中是用vector做容器实现的。根据heap的父节点和子节点的关系(i , 2i , 2i+1 )

【2】heap的pop操作中,取出跟节点,完成pop后,并没有删除,而是放到了vector的最后元素,由pop步骤图可以看出;

【3】heap没有迭代器,虽然vector有迭代器,但是作为底层容器封装成heap后,heap没有提供迭代器


priority_queue


priority_queue也不是一种严格意义的容器,也是一种容器配接器

根据heap的特性,每次都取出最大货最小值,那么priority_queue就的出队序列就可以根据heap的根节点确定了,而不是入队顺序。

所以只要在heap之上再做封装,就可以实现了。

STL源码剖析之heap,priority_queue【2013.11.25】_第9张图片STL源码剖析之heap,priority_queue【2013.11.25】_第10张图片

根据代码可以看出,底层还是默认Vector,可以指定底层的实现容器。

和queue不同的是 push和pop方法,是用到了,建立heap和出heap的方法,实现构造一个大小堆,出堆(取最大小元素),

值得注意的是,定义的时候多了一个Compare ,这个是在push和pop 堆的时候的比较规则,当是特殊元素的时候,就需要指定对应的compare 仿函数!


【1】没有迭代器


附录priority_queue使用范例:

STL源码剖析之heap,priority_queue【2013.11.25】_第11张图片


欢迎加入我们的QQ群,无论你是否工作,学生,只要有c / vc / c++ 编程经验,就来吧!158427611 【IT】C/C++/STL/Linux/W

你可能感兴趣的:(C++,heap,priority_queue,STL,SGI)