zoukankan      html  css  js  c++  java
  • C++ STL源代码学习(map,set内部heap篇)

    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);
    }
    
    


  • 相关阅读:
    递归函数
    Java以缓冲字符流向文件写入内容(如果文件存在则删除,否则先创建后写入)
    Python将文本内容读取分词并绘制词云图
    查询数据库数据并传入servlet
    向数据库添加记录(若有则不添加)
    2月16日学习记录
    2月15日学习记录
    2月14日学习记录
    Echart学习
    JavaScript深入学习(六)Ajax技术
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4068999.html
Copyright © 2011-2022 走看看