①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. 【转】如何用WINDBG分析64位机上32位程序的DUMP文件

    将dump拖入到windbg中后,在command输入栏输入 .load wow64exts 回车 !sw 回车,就将windbg的dump,从64位模式切换到了32位模式,否则看到的call sta ...

  2. RMQ(dp)

    我一开始是不知道有这么个东西,但是由于最近在学习后缀数组,碰到一道题需要用到后缀数组+RMQ解决的所以不得不学习了. 原理:用A[1...n]表示一组数,dp[i][j]表示从A[i]到A[i+2^j ...

  3. 用Apache Kafka构建流数据平台的建议

    在<流数据平台构建实战指南>第一部分中,Confluent联合创始人Jay Kreps介绍了如何构建一个公司范围的实时流数据中心.InfoQ前期对此进行过报道.本文是根据第二部分整理而成. ...

  4. 编程式事务、XML配置事务、注解实现事务

    Spring2.0框架的事务处理有两大类: 1 编码式事务 , 这个不说. 2 声明式事务 , 就说这个. 声明式事务又有三种实现方法: 1 (第一种) 最早的方法,用TransactionProxy ...

  5. Android中ListView中有button,checkbox,GridView时事件问题

    最近做项目,用到了listview的item的一些问题,现在抽空把它们总结一下: 转载请表明出处:http://blog.csdn.net/wdaming1986/article/details/67 ...

  6. LoadRunner检查点实战

    码农博客 即将到期,现将博客中部分文章转载到博客园.转载时略有删减. 一.为什么要使用检查点 为什么要使用检查点,那就要说明一下LR如何判断脚本是否执行成功. LR判断脚本是否执行成功是根据服务器返回 ...

  7. Selenium用户扩展

    Selenium用户扩展 这很容易扩展Selenium IDE加入自定义操作,断言和定位,策略,这是通过添加方法,在JavaScript的帮助下Selenium 对象原型.在启动时,Selenium会 ...

  8. 快速开发 jQuery 插件的 10 大技巧(转)

    转自:http://www.oschina.net/news/41776/jquery-10-tips 在开发过很多 jQuery 插件以后,我慢慢的摸索出了一套开发jQuery插件比较标准的结构和模 ...

  9. Java 简繁转换 ZHConverter

    Sample import com.spreada.utils.chinese.ZHConverter; public class Test{ public static void main(Stri ...

  10. pomelo windows 环境

    1.先安装 Python; 通过Python 官网 http://www.python.org/getit/ 下载并安装最新版本. 然后将Python 的安装目录(如: C:\Program File ...