stl_heap.h

///STL中使用的是大顶堆
/// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap.
template <class _RandomAccessIterator, class _Distance, class _Tp>
void
__push_heap(_RandomAccessIterator __first,
_Distance __holeIndex, _Distance __topIndex, _Tp __value)
{
_Distance __parent = (__holeIndex - 1) / 2; ///逐层上溯,查找要插入的位置
while (__holeIndex > __topIndex && *(__first + __parent) < __value) {
*(__first + __holeIndex) = *(__first + __parent);
__holeIndex = __parent;
__parent = (__holeIndex - 1) / 2;
} ///找到位置,插入
*(__first + __holeIndex) = __value;
} template <class _RandomAccessIterator, class _Distance, class _Tp>
inline void
__push_heap_aux(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Distance*, _Tp*)
{
__push_heap(__first, _Distance((__last - __first) - 1), _Distance(0),
_Tp(*(__last - 1)));
} template <class _RandomAccessIterator>
inline void
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
__STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
_LessThanComparable); __push_heap_aux(__first, __last,
__DISTANCE_TYPE(__first), __VALUE_TYPE(__first));
} template <class _RandomAccessIterator, class _Distance, class _Tp,
class _Compare>
void
__push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
_Distance __topIndex, _Tp __value, _Compare __comp)
{
_Distance __parent = (__holeIndex - 1) / 2;
while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) {
*(__first + __holeIndex) = *(__first + __parent);
__holeIndex = __parent;
__parent = (__holeIndex - 1) / 2;
}
*(__first + __holeIndex) = __value;
} template <class _RandomAccessIterator, class _Compare,
class _Distance, class _Tp>
inline void
__push_heap_aux(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp,
_Distance*, _Tp*)
{
__push_heap(__first, _Distance((__last - __first) - 1), _Distance(0),
_Tp(*(__last - 1)), __comp);
} template <class _RandomAccessIterator, class _Compare>
inline void
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
__push_heap_aux(__first, __last, __comp,
__DISTANCE_TYPE(__first), __VALUE_TYPE(__first));
} ///将__holeIndex处的结点摘掉,并保持合法的大顶堆状态,然后插入__value
///运行此函数前,必须保证以__holeIndex为根节点构成的全然二叉树符合大顶堆的定义
template <class _RandomAccessIterator, class _Distance, class _Tp>
void
__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
_Distance __len, _Tp __value)
{
_Distance __topIndex = __holeIndex;
_Distance __secondChild = 2 * __holeIndex + 2;
///向下遍历,从__holeIndex中找出两个孩子中较大的一个填入__holeIndex,并令__holeIndex
///等于该孩子,继续运行,直至__holeIndex无孩子或者仅仅有一个孩子(为了占被摘取的那个节点的位置)
while (__secondChild < __len) {
if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
__secondChild--;
*(__first + __holeIndex) = *(__first + __secondChild);
__holeIndex = __secondChild;
__secondChild = 2 * (__secondChild + 1);
} if (__secondChild == __len) { ///__holeIndex仅仅有一个孩子,补充上去
*(__first + __holeIndex) = *(__first + (__secondChild - 1));
__holeIndex = __secondChild - 1;
} ///至此,大顶堆合法,插入__value
__push_heap(__first, __holeIndex, __topIndex, __value);
} template <class _RandomAccessIterator, class _Tp, class _Distance>
inline void
__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_RandomAccessIterator __result, _Tp __value, _Distance*)
{
///该函数并未删除弹出的那个元素,而仅仅是将它移动到最后面
*__result = *__first;
__adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value);
} template <class _RandomAccessIterator, class _Tp>
inline void
__pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Tp*)
{
__pop_heap(__first, __last - 1, __last - 1,
_Tp(*(__last - 1)), __DISTANCE_TYPE(__first));
} template <class _RandomAccessIterator>
inline void pop_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
__STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
_LessThanComparable); __pop_heap_aux(__first, __last, __VALUE_TYPE(__first));
} template <class _RandomAccessIterator, class _Distance,
class _Tp, class _Compare>
void
__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
_Distance __len, _Tp __value, _Compare __comp)
{
_Distance __topIndex = __holeIndex;
_Distance __secondChild = 2 * __holeIndex + 2;
while (__secondChild < __len) {
if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1))))
__secondChild--;
*(__first + __holeIndex) = *(__first + __secondChild);
__holeIndex = __secondChild;
__secondChild = 2 * (__secondChild + 1);
}
if (__secondChild == __len) {
*(__first + __holeIndex) = *(__first + (__secondChild - 1));
__holeIndex = __secondChild - 1;
}
__push_heap(__first, __holeIndex, __topIndex, __value, __comp);
} template <class _RandomAccessIterator, class _Tp, class _Compare,
class _Distance>
inline void
__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_RandomAccessIterator __result, _Tp __value, _Compare __comp,
_Distance*)
{
*__result = *__first;
__adjust_heap(__first, _Distance(0), _Distance(__last - __first),
__value, __comp);
} template <class _RandomAccessIterator, class _Tp, class _Compare>
inline void
__pop_heap_aux(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Tp*, _Compare __comp)
{
__pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp,
__DISTANCE_TYPE(__first));
} template <class _RandomAccessIterator, class _Compare>
inline void
pop_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
__pop_heap_aux(__first, __last, __VALUE_TYPE(__first), __comp);
} template <class _RandomAccessIterator, class _Tp, class _Distance>
void
__make_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Tp*, _Distance*)
{
if (__last - __first < 2) return;
_Distance __len = __last - __first; ///因为__adjust_heap的要求,必须从最底层開始逐层向上调整.
_Distance __parent = (__len - 2)/2; ///此时它的两个孩子分别为__len-1,len while (true) {
__adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)));
if (__parent == 0) return;
__parent--;
}
} template <class _RandomAccessIterator>
inline void
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
__STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
_LessThanComparable); __make_heap(__first, __last,
__VALUE_TYPE(__first), __DISTANCE_TYPE(__first));
} template <class _RandomAccessIterator, class _Compare,
class _Tp, class _Distance>
void
__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp, _Tp*, _Distance*)
{
if (__last - __first < 2) return;
_Distance __len = __last - __first;
_Distance __parent = (__len - 2)/2; while (true) {
__adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)),
__comp);
if (__parent == 0) return;
__parent--;
}
} template <class _RandomAccessIterator, class _Compare>
inline void
make_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); __make_heap(__first, __last, __comp,
__VALUE_TYPE(__first), __DISTANCE_TYPE(__first));
} template <class _RandomAccessIterator>
void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
__STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
_LessThanComparable); ///因为pop_heap函数并未正真将结点删除,此函数得以实现
while (__last - __first > 1)
pop_heap(__first, __last--);
} template <class _RandomAccessIterator, class _Compare>
void
sort_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
while (__last - __first > 1)
pop_heap(__first, __last--, __comp);
}

C++ STL源代码学习(map,set内部heap篇)的更多相关文章

  1. C++ STL源代码学习之算法篇

    ///因为篇幅太长,因此,删去了非常多接口,仅仅分析了内部实现,算法对迭代器的要求也被删去 /// search. template <class _ForwardIter1, class _F ...

  2. STL源代码学习--vector用法汇总

    一.容器vector 使用vector你必须包含头文件<vector>: #include<vector> 型别vector是一个定义于namespace std内的templ ...

  3. C++ STL源代码学习(list篇)

    ///STL list为双向循环链表 struct _List_node_base { _List_node_base* _M_next; _List_node_base* _M_prev; }; t ...

  4. C++ STL 源代码学习(之deque篇)

    stl_deque.h /** Class invariants: * For any nonsingular iterator i: * i.node is the address of an el ...

  5. C++STL源代码学习(之slist篇)

    ///stl_slist.h ///list为双向循环链表,slist为单向链表.某些操作效率更高 ///slist是SGI额外提供的单向链表,不属于C++标准 struct _Slist_node_ ...

  6. STL源代码学习(vector篇)

    #include <concept_checks.h> #include<stl_allocate.h> /// The vector base class's constru ...

  7. STL的pair学习, map学习

    http://blog.csdn.net/calvin_zcx/article/details/6072286 http://www.linuxidc.com/Linux/2014-10/107621 ...

  8. STL源代码分析——STL算法sort排序算法

    前言 因为在前文的<STL算法剖析>中,源代码剖析许多,不方便学习,也不方便以后复习.这里把这些算法进行归类,对他们单独的源代码剖析进行解说.本文介绍的STL算法中的sort排序算法,SG ...

  9. STL中关于map和set的四个问题?

    STL map和set的使用虽不复杂,但也有一些不易理解的地方,如: 为何map和set的插入删除效率比用其他序列容器高? 或许有得人能回答出来大概原因,但要彻底明白,还需要了解STL的底层数据结构. ...

随机推荐

  1. iOS开发-21UINavigationController导航控制器初始化 导航控制器栈的push和pop跳转理解

    (1)导航控制器初始化的时候一般都有一个根视图控制器,导航控制器相当于一个栈,里面装的是视图控制器,最先进去的在最下面,最后进去的在最上面.在最上面的那个视图控制器的视图就是这个导航控制器对外展示的界 ...

  2. Oracle SQL函数之字符串函数

    1.SQL> ) from dual; --ASCLL(x)返回x的ASCLL码,CHR(x)返回ASCLL码为x的字符 ASCII() ---------- ---------- ------ ...

  3. resolv.conf 是什么

    From Wikipedia, the free encyclopedia This article does not cite any references or sources. Please h ...

  4. (原创) C# List 找 Max 的 Index

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  5. 使用xib方式创建UITableViewCell,设置Label自动换行注意事项

    自定义的UITableViewCell,使用xib方式创建,想要其中的UILabel换行显示:计算Label的高度,让其自动换行,总是没有效果. 我猜测原因可能在于使用了autolayout布局.只要 ...

  6. UVALive 6959 - Judging Troubles

    给两组字符串,最多有多少对相同. map做映射判断一下. #include <iostream> #include <cstdio> #include <map> ...

  7. centos安装如何选择安装包

    1.根据经验,选择安装包时应该按最小化原则,即不需要的或者不确定是否需要的就不安装,这样可以最大程度上确保系统安全. 2.如果安装过程落了部分包组或者其他伙伴安装时没选,再安装后可以按如下方式补上安装 ...

  8. python之列表、字典的使用

    一.概述:以后你在Linux里面写Python脚本的时候会经常用到Python列表.字典,因为你在以后写脚本的时候,大多数情况下都是对文件进行操作处理,使用字典和列表可以很好的操作文件,得出你想要的结 ...

  9. Linux下Nginx+PHP 简单安装配置

    测试环境 Linux 2.6.18nginx-1.0.4 http://www.nginx.org/php-5.3.6 http://www.php.net/ 一,安装Nginxwget http:/ ...

  10. delphi idhttp 实战用法(TIdhttpEx)

    以delphi XE8 自带indy(10.5.8.0)组件为例,分享实战中遇到的问题及解决方法. TIdHttpEx 用法实例01[多线程获取网页](包含完整源码) 实例02(如何Post参数,如何 ...