zoukankan      html  css  js  c++  java
  • 《STL源代码分析》---stl_heap.h读书笔记

    Heap堆的数据结构是经常使用,Heap它还能够存储元件的。但STL并且不提供Heap集装箱。仅仅提供信息Heap算术运算。只支持RandomAccessIterator该容器可以被用作Heap集装箱。
    Heapmax heap和min heap。max heap中每次取出的结点时heap结构中值最大的结点,min heap中每次取出的结点时heap结构中值最小的结点。
    在实际应用中。常常常使用vector作为heap容器,heap常常作为priority queue。对于二叉堆。这里有描写叙述http://blog.csdn.net/kangroger/article/details/8718732
    当向heap中插入元素时,插入到末尾,“向上维护”就可以:指的是把插入结点与其父结点比較,假设不符合堆得要求则交换,再向上维护其父结点……
    当在heap取出元素时,把末尾元素放到Heap头。"向下维护“就可以:指的是父结点与孩子结点比較。假设不满足要求,与较大(较小)一个交换,再维护交换的孩子结点……

    Heap不同意遍历其结点,所以Heap没有迭代器。

    G++ 2.91.57,cygnuscygwin-b20includeg++stl_heap.h 完整列表
    /*
     *
     * Copyright (c) 1994
     * Hewlett-Packard Company
     *
     * Permission to use, copy, modify, distribute and sell this software
     * and its documentation for any purpose is hereby granted without fee,
     * provided that the above copyright notice appear in all copies and
     * that both that copyright notice and this permission notice appear
     * in supporting documentation.  Hewlett-Packard Company makes no
     * representations about the suitability of this software for any
     * purpose.  It is provided "as is" without express or implied warranty.
     *
     * Copyright (c) 1997
     * Silicon Graphics Computer Systems, Inc.
     *
     * Permission to use, copy, modify, distribute and sell this software
     * and its documentation for any purpose is hereby granted without fee,
     * provided that the above copyright notice appear in all copies and
     * that both that copyright notice and this permission notice appear
     * in supporting documentation.  Silicon Graphics makes no
     * representations about the suitability of this software for any
     * purpose.  It is provided "as is" without express or implied warranty.
     */
    
    /* NOTE: This is an internal header file, included by other STL headers.
     *   You should not attempt to use it directly.
     */
    
    #ifndef __SGI_STL_INTERNAL_HEAP_H
    #define __SGI_STL_INTERNAL_HEAP_H
    
    __STL_BEGIN_NAMESPACE
    
    #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
    #pragma set woff 1209
    #endif
    
    
    //向上维护
    template <class RandomAccessIterator, class Distance, class T>
    void __push_heap(RandomAccessIterator first, Distance holeIndex,
                     Distance topIndex, T value) {
      Distance parent = (holeIndex - 1) / 2;	// 找出父结点
      //父结点不是heap顶 且 父节点的值小于孩子结点(小于号<能够看出STL维护的是max heap)
      while (holeIndex > topIndex && *(first + parent) < value) {
        *(first + holeIndex) = *(first + parent);	// 父结点下调
        holeIndex = parent; // 维护父结点
        parent = (holeIndex - 1) / 2;	
      }    
      //已达到heap顶或者满足heap性质后,给新插入元素找到合适位置
      *(first + holeIndex) = value;	
    }
    
    template <class RandomAccessIterator, class Distance, class T>
    inline void __push_heap_aux(RandomAccessIterator first,
                                RandomAccessIterator last, Distance*, T*) {
      __push_heap(first, Distance((last - first) - 1), Distance(0), 
                  T(*(last - 1)));
      
    }
    
    //往heap加入元素。注意:此函数调用时。元素已经加入到末尾了,且迭代器已经加1了
    template <class RandomAccessIterator>
    inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) {
      // 注意,此函式被呼叫時,新元素應已置於底層容器的最尾端。
      __push_heap_aux(first, last, distance_type(first), value_type(first));
    }
    
    //向上维护,同意用自定义的comp函数,这是未必是max heap了
    template <class RandomAccessIterator, class Distance, class T, class Compare>
    void __push_heap(RandomAccessIterator first, Distance holeIndex,
                     Distance topIndex, T 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 T>
    inline void __push_heap_aux(RandomAccessIterator first,
                                RandomAccessIterator last, Compare comp,
                                Distance*, T*) {
      __push_heap(first, Distance((last - first) - 1), Distance(0), 
                  T(*(last - 1)), comp);
    }
    
    template <class RandomAccessIterator, class Compare>
    inline void push_heap(RandomAccessIterator first, RandomAccessIterator last,
                          Compare comp) {
      __push_heap_aux(first, last, comp, distance_type(first), value_type(first));
    }
    
    // 下面這個 __adjust_heap() 不允許指定「大小比較標準」
    //向下维护heap
    template <class RandomAccessIterator, class Distance, class T>
    void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
                       Distance len, T value) {
      Distance topIndex = holeIndex;
      Distance secondChild = 2 * holeIndex + 2;	// 找到右孩子的位置
      while (secondChild < len) {//还没到达末尾
        // 比較左右孩子大小, secondChild 代表当中较大者
        if (*(first + secondChild) < *(first + (secondChild - 1)))
          secondChild--;   
        // 较大的孩子放到父结点位置
        *(first + holeIndex) = *(first + secondChild);  
        holeIndex = secondChild;
        // 维护较大的孩子
        secondChild = 2 * (secondChild + 1);
      }
      // 没有右孩子,仅仅有左孩子,仅仅需维护一次,由于左孩子是heap的最后一个元素
      if (secondChild == len) { 
        *(first + holeIndex) = *(first + (secondChild - 1));
        holeIndex = secondChild - 1;
      }
    
      //把调整值放到合适位置,等价于*(first + holeIndex) = value;
      __push_heap(first, holeIndex, topIndex, value);
    }
    
    //向下维护heap
    template <class RandomAccessIterator, class T, class Distance>
    inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
                           RandomAccessIterator result, T value, Distance*) {
      *result = *first; // 把堆顶的值放到堆尾,堆尾的值保存在參数value中
                          
      __adjust_heap(first, Distance(0), Distance(last - first), value);
     
    }
    
    template <class RandomAccessIterator, class T>
    inline void __pop_heap_aux(RandomAccessIterator first,
                               RandomAccessIterator last, T*) {
      __pop_heap(first, last-1, last-1, T(*(last-1)), distance_type(first));
      /*
    	依据implicit representation heap的次序性,pop后的结果是容器的第一个元素。

    把最后一个元素放到到容器头,因此维护时维护区间是[first last-1)。

    */ } //取出heap顶元素,依照max heap属性来维护heap template <class RandomAccessIterator> inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) { __pop_heap_aux(first, last, value_type(first)); } //向下维护heap,同意运行比較函数comp template <class RandomAccessIterator, class Distance, class T, class Compare> void __adjust_heap(RandomAccessIterator first, Distance holeIndex, Distance len, T 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); } // 取出堆顶元素。同意定义比較函数comp template <class RandomAccessIterator, class T, class Compare, class Distance> inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last, RandomAccessIterator result, T value, Compare comp, Distance*) { *result = *first; __adjust_heap(first, Distance(0), Distance(last - first), value, comp); } template <class RandomAccessIterator, class T, class Compare> inline void __pop_heap_aux(RandomAccessIterator first, RandomAccessIterator last, T*, Compare comp) { __pop_heap(first, last - 1, last - 1, T(*(last - 1)), comp, distance_type(first)); } //取出heap顶元素,依据comp调整heap template <class RandomAccessIterator, class Compare> inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { __pop_heap_aux(first, last, value_type(first), comp); } template <class RandomAccessIterator, class T, class Distance> void __make_heap(RandomAccessIterator first, RandomAccessIterator last, T*, Distance*) { if (last - first < 2) return; Distance len = last - first; Distance parent = (len - 2)/2; //从heap的中间開始向下维护。一次维护[parent, parent-1,……,0] while (true) { __adjust_heap(first, parent, len, T(*(first + parent))); if (parent == 0) return; parent--; } } // 将 [first,last) 排列成一个 heap。 template <class RandomAccessIterator> inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) { __make_heap(first, last, value_type(first), distance_type(first)); } template <class RandomAccessIterator, class Compare, class T, class Distance> void __make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp, T*, Distance*) { if (last - first < 2) return; Distance len = last - first; //从heap的中间開始向下维护。一次维护[parent, parent-1,……,0] Distance parent = (len - 2)/2; while (true) { __adjust_heap(first, parent, len, T(*(first + parent)), comp); if (parent == 0) return; parent--; } } // 将 [first,last) 排列成一个 heap。同意运行大小比較函数 template <class RandomAccessIterator, class Compare> inline void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { __make_heap(first, last, comp, value_type(first), distance_type(first)); } // 排序(升序)两个迭代器之间的元素,这两个迭代器之间的元素已经满足heap性质了 template <class RandomAccessIterator> void sort_heap(RandomAccessIterator first, RandomAccessIterator last) { /* pop_heap()功能是删除heap顶元素,把heap大小减小1,heap顶元素放到末尾。

    由此能够看出,sort的结果是升序。 */ while (last - first > 1) pop_heap(first, last--); // 每執行 pop_heap() 一次,操作範圍即退縮一格。 } // 排序(升序)两个迭代器之间的元素,这两个迭代器之间的元素已经满足heap性质了。 //同意指定比較函数comp template <class RandomAccessIterator, class Compare> void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { while (last - first > 1) pop_heap(first, last--, comp); } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1209 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_HEAP_H */ // Local Variables: // mode:C++ // End:




    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    CGI编程完全手册(转)
    Linux下读写芯片的I2C寄存器(转)
    Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法与解析
    H264中的SPS、PPS提取与作用(转)
    H264码流打包分析(精华)--转
    嵌入式Linux USB WIFI驱动的移植(转)
    推荐一款技术人必备的接口测试神器:Apifox
    Java 设置、删除、获取Word文档背景(基于Spire.Cloud.SDK for Java)
    Java 添加、删除、格式化Word中的图片( 基于Spire.Cloud.SDK for Java )
    Java 添加、删除、替换、格式化Word中的文本(基于Spire.Cloud.SDK for Java)
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4820271.html
Copyright © 2011-2022 走看看