①push_heap算法

以下是push_heap算法的实现细节。该函数接收两个迭代器,用来表现一个heap底部容器(vector)的头尾,而且新元素已经插入究竟部的最尾端。

template <class RandomAccessIterator>

inline void push_heap(RandomAccessIterator first,RandomAccessIterator last)

{

 //注意,此函数被调用时,新元素应已置于底部容器的最尾端

 _push_heap_aux(first,last,distance_type(first),value_type(first)); 

}

template <class RandomAccessIterator,class Distance,class T>

inline void _push_heap_aux(RandomAccessIterator first,RandomAccessIterator last,

Distance*,T*)

{

 //以上系依据heap的结构特性:新值必置于底部容器的最尾端,此即第一个洞号:(last-first)-1

 _push_heap(first,Distance((last-first)-1),Distance(0),T(*(last-1)));

}

template <class RandomAccessIterator,class Distance,class T>

void _push_heap(RandomAccessIterator first,Distance holeIndex,Distance topIndex,T value)

{

 Distance parent = (holeIndex-1)/2;

 while (parent > topIndex && *(first+parent)<value)

 {

  *(first + holeIndex) = *(first + parent);

  holeIndex = parent;

  parent = (holeIndex-1)/2;

 }

 *(first + holeIndex) = value;

}

②pop_heap算法

pop操作取走根节点(事实上是设至底部容器vector的尾端节点)后,为了满足complete binary tree的条件,必须割舍最下层最右边的叶节点,并将其值又一次安插至最大堆。

template <class RandomAccessIterator>

inline void pop_heap(RandomAccessIterator first,RandomAccessIterator last)

{

 _pop_heap_aux(first,last,value_type(first));

}

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

}

template <class RandomAccessIterator,class T,class Distance>

inline void _pop_heap(RandomAccessIterator first,RandomAccessIterator last,RandomAccessIterator result,

T value,Distance*)

{

 *result = *first;

 _adjust_heap(first,Distance(0),Distance(last-first),value);

 //以上欲又一次调整heap,洞号为0(亦即树根处),欲调整值为value(原尾值)

}

template <class RandomAccessIterator,class Distance,class T>

void _adjust_heap(RandomAccessIterator first,Distance holeIndex,Distance len,T value)

{

 Distance topIndex = holeIndex;

 Distance secondChild = holeIndex*2+2;

 while (secondChild < len)

 {

  if(*(first+secondChild) < *(first+secondChild-1))

   secondChild--;

  *(first+holeIndex) = *(first+secondChild);

  holeIndex = secondChild;

  secondChild = holeIndex*2+2;

 }

 if (secondChild == len)

 {

  *(first+holeIndex) = *(first+secondChild-1);

  holeIndex = secondChild-1;

 }

 _push_heap(first,holeIndex,topIndex,value);

}

注意:pop_heap之后,最大元素仅仅是被置于底部容器的最尾端,尚未被取走。假设要取其值,可使用底部容器(vector)所提供的back()操作函数。假设要移除它,可使用底部容器(vector)所提供的pop_back()操作函数。

③sort_heap算法

既然每次pop_heap可获得heap中键值最大的元素,假设持续对整个heap做pop_heap操作,每次将操作范围从后向前缩减一个元素(由于pop_heap会把键值最大的元素放在底部容器的最尾端),当整个程序运行完成时,我们便有了一个递增序列。

template<class RandomAccessIterator>

void sort_heap(RandomAccessIterator first,RandomAccessIterator last)

{

 while(last - first > 1)

  pop_heap(first,last--);

}

④make_heap算法

这个算法用来将一段现有的数据转化为一个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 T,class Distance>

void _make_heap(RandomAccessIterator first,RandomAccessIterator last,T*,Distance*)

{

 if (last - first < 2) return;

 Distance len  = last-first;

 Distance parent = (len-1)/2;

while (true)

 {

  _adjust_heap(first,parent,len,T(*(first+parent)));

  if (parent == 0)

   return;

  parent--;

 }

}

STL中heap算法(堆算法)的更多相关文章

  1. L2-012. 关于堆的判断(STL中heap)

    L2-012. 关于堆的判断   将一系列给定数字顺序插入一个初始为空的小顶堆H[].随后判断一系列相关命题是否为真.命题分下列几种: “x is the root”:x是根结点: “x and y ...

  2. STL中heap相关函数

    heap并不是属于STL中的containers,而是在<algorithm>下提供了相关的函数 make_heap,sort_heap,pop_heap,push_heap 函数的说明: ...

  3. stl中常用的排序算法

    #include"iostream" #include"vector" using namespace std; #include"string&qu ...

  4. java 中 heap(堆)和stack(栈)的区别

    总结在Java里面Heap和Stack分别存储数据的不同. 区别项 Heap(堆) Stack(栈) JVM中的功能 内存数据区 内存指令区 存储数据 对象实例(注1) 基本数据类型, 指令代码,常量 ...

  5. STL中heap用法

    #include<cstdio> #include<iostream> #include<algorithm> using namespace std; ]={,, ...

  6. 论C++STL源代码中关于堆算法的那些事

    关于堆,我们肯定熟知的就是它排序的时间复杂度在几个排序算法里面算是比較靠上的O(nlogn)常常会拿来和高速排序和归并排序讨论,并且它还有个长处是它的空间复杂度为O(1), 可是STL中没有给我们提供 ...

  7. STL源码剖析:算法

    启 算法,问题之解法也 算法好坏的衡量标准:时间和空间,单位是对数.一次.二次.三次等 算法中处理的数据,输入方式都是左闭又开,类型就迭代器, 如:[first, last) STL中提供了很多算法, ...

  8. C++ STL中Map的按Key排序和按Value排序

    map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区 分),我们用map来进 ...

  9. C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET

    C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET C++ STL中Map的相关排序操作:按Key排序和按Value排序 分类: C ...

随机推荐

  1. Oracle 创建和使用视图

    一.what(什么是视图?) 1.视图是一种数据库对象,是从一个或者多个数据表或视图中导出的虚表,视图所对应的数据并不真正地存储在视图中,而是存储在所引用的数据表中,视图的结构和数据是对数据表进行查询 ...

  2. [转] AE中如何由IFeature 如何获取所对应的FeatureClass

    转载的原文 AE中如何由IFeature 如何获取所对应的FeatureClass   先获取FeatureClass,然后遍历Map中所有的FeatureLayer,然后比较 FeatureClas ...

  3. [Papers]NSE, $u_3$, Lebesgue space [NNP, QM, 2002; Zhou, JMPA, 2005]

    $$\bex u_3\in L^p(0,T;L^q(\bbR^3)),\quad \frac{2}{p}+\frac{3}{q}=\frac{1}{2},\quad 6< q\leq \inft ...

  4. BLOCK 死循环

    __weak typeof(self) weakSelf = self; myObj.myBlock =  ^{     __strong typeof(self) strongSelf = weak ...

  5. cocos2d CCLayer 触摸相关

    要让一个  CCLayer 能够接受触摸输入  需要进行如下设置: [selfsetTouchEnabled:YES]; cocos2d-x提供了两种触摸事件处理机制, 分别是CCStandardTo ...

  6. 我喜欢的乐队-Euphoria

    来自日本的后摇乐团,001年冬天由森川裕之.佐藤昭太.木下阳辅三人于东京组建,2003年签约日本独立厂牌123Record,并发行首张EP细碟<Floral Dew>.包括EP.Singl ...

  7. 踩刹车——regularization

    从一个问题说起: 当我们使用H10去拟合曲线的时候,其实我们只想要H2的结果.如果从H10变回到H2呢? 所以我们只需要添加上限制条件:w3=...=w10=0即可.现在呢,我们可以放宽一点条件:任意 ...

  8. oc_转_NSArrray 和 NSMutableArrray

    Objective C 中除了可以使用C中的基本数组外,如 int[5];,char word[] = {‘a’, 'b’, 'c’};,Foundation 还提供了 NSArray 类.Found ...

  9. Navicate

    快捷键 1.ctrl+q 打开查询窗口 2.ctrl+/ 注释sql语句 3.ctrl+shift +/ 解除注释 4.ctrl+r 运行查询窗口的sql语句 5.ctrl+shift+r 只运行选中 ...

  10. [转]天龙八部服务器端Lua脚本系统

    一.Lua脚本功能接口 1. LuaInterface.h/.cpp声明和实现LuaInterface. LuaInterface成员如下: //脚本引擎 FoxLuaScriptmLua ; //注 ...