STL heap并不是容器,而是一系列的算法。
这些算法接受RandomAccessIterator[start, end),并将其表述成一棵完全二叉树。
关于heap算法可以参考之前算法导论的一篇博客:http://www.cnblogs.com/runnyu/p/4677170.html。
先看看heap算法的接口
1 // 改变[first, last)元素的次序 使其变成一个max_heap 2 // 其实现就是堆排序中的建堆过程 3 template <class RandomAccessIterator> 4 inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) { ... } 5 6 /* 7 将元素插入堆中 并维护堆的性质(详细看下面的图解) 8 (在执行push_heap之前就应该把元素push_back到容器最后 如: 9 vec.push_back(1); 10 push_heap(vec.begin(), vec.end());) 11 12 虽然这样子接口看起来有点奇怪 但是如果操作的是vector 13 将要插入的元素作为第三个参数的话 在该函数进行插入的时候 14 可能vector会进行扩容 导致传进来的迭代器失效 15 */ 16 template <class RandomAccessIterator> 17 inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) { ... } 18 19 // 将尾元素替换成首元素(max) 并维护堆的性质 20 // 旧的尾元素会插入到适当的位置 21 // 然后由客户端调用pop_back等方法移除尾元素(具体看下面图解) 22 template <class RandomAccessIterator> 23 inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) { ... } 24 25 // 每次调用pop_heap将最大的元素移到最后 实现排序 26 template <class RandomAccessIterator> 27 void sort_heap(RandomAccessIterator first, RandomAccessIterator last) 28 { 29 while (last - first > 1) pop_heap(first, last--, comp); 30 }
下图是push_heap()的图解
下图是pop_back()的图解
再参照堆排序的实现,heap算法的实现就很容易理解了,具体代码我就不贴了。
下一次会讲几个容器适配器: priority_queue(底层使用heap算法实现)、stack(默认使用deque实现)、queue(默认使用deuqe实现)。