STL源码剖析之heap,priority_queue【2013.11.25】
欢迎加入我们的QQ群,无论你是否工作,学生,只要有c / vc / c++ 编程经验,就来吧!158427611
heap不是容器,但是却是实现priority_queue的关键,由他实现权重排列。实现权重出队。
heap
heap在数据结构中,是一种堆的概念(二叉堆,这里分为大堆[max_heap]和小堆[min_heap],即最大值,最小值位于堆的跟节点,下图A)。
对于堆的概念
所谓的大堆就是 父节点比子节点大,同样小堆就是父节点小于子节点。这样保持根节点永远是最大或最小的。
由于堆的特殊性质,完全二叉树,所以堆的数据可以用一个连续空间表示,其父子节点之间的关系可以是 A为第0个,其子节点A,B就是第 1 ,2个,即 2i和2i+1;
对于堆,在priority_queue中,最重要的就是heap的取出算法,即每次取最大或最小(pop);当然还有构造一个heap(push);
【1】构造heap就是一个一个节点push进heap;
第一个即为根节点,之后的push,则是和父节点比较,如果大就互换父子节点,再向上取父节点,循环。看图:
代码如下:
【2】取出堆POP,就是直接取跟节点,然后对应的互换子节点。保证堆的规范。
先取跟节点,然后判断两个子节点,大的子节点变成父节点;
然后并继续向下,左右子节点判断,取大的,并和堆的最后一个节点比较,如果最后一个大就把最后一个直接放到此节点,否则就是取大的子节点变父节点,继续向下重复操作
如图:
代码如下:
【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之上再做封装,就可以实现了。
根据代码可以看出,底层还是默认Vector,可以指定底层的实现容器。
和queue不同的是 push和pop方法,是用到了,建立heap和出heap的方法,实现构造一个大小堆,出堆(取最大小元素),
值得注意的是,定义的时候多了一个Compare ,这个是在push和pop 堆的时候的比较规则,当是特殊元素的时候,就需要指定对应的compare 仿函数!
【1】没有迭代器
附录priority_queue使用范例:
欢迎加入我们的QQ群,无论你是否工作,学生,只要有c / vc / c++ 编程经验,就来吧!158427611