①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. C# 如何以参数的形式调用.exe程序

    System.Diagnostics.Process.Start("程序的路径", "参数1 参数2");第一个参数是aaa.exe 的路径,第二个参数是用空格 ...

  2. 对delegate进行扩展 打造通用的"计时完成"方法 z

    让用户尽量少打字 每次让用户输入这么多信息的确很糟糕, 可以改进一下设计: 服务器IP和用户名可以存放在配置文件里面, 初始化的时候默认加载到相应的文本框中; 从安全角度考虑, 密码必须经过用户手动输 ...

  3. Redrain个人维护并使用的DuiLib和UiLib库源码下载地址

    转载请说明原出处:http://blog.csdn.net/zhuhongshu/article/details/40740353,谢谢~~ 我把我自己使用的Duilib库和Uilib库都上传到了Gi ...

  4. C++第一章概述

    1:C++主要是对于C的继承性做的相当的出色,主要扩充在于程序员可以自己定义自己的数据结构,用数据结构去描述日常生活中的事务,而不是C语言中当当仅有的Struct数据类型等等 2: 每一种语言都有自己 ...

  5. 发布 asp.net网站 到本地IIS

    http://blog.csdn.net/jiben2qingshan/article/details/9249139 概述 网站是由一个个页面组成的,是万维网具体的变现形式,关于万维网,网页的方面的 ...

  6. php环境配置中各个模块在网站建设中的功能

    上一篇配置环境的时候,我们注意到,有四个模块需要配置,那么,这四个模块分别有哪些功能呢?   一.php php是我们的用来创建动态网页的强有力的脚本语言,安装过程中我们直接解压到某一个路径就好了,比 ...

  7. 时间都去哪了?——安卓GTD工具

    GTD是英文Getting Things Done的缩写,是一种行为管理的方法,也是David Allen写的一本书的书名. GTD的主要原则在于一个人需要通过记录的方式把头脑中的各种任务移出来.通过 ...

  8. 快速备份sqlserver2005以上版本数据库的方法-摘自网络

    使用优化参数的备份命令 BACKUP DATABASE [test]TO DISK = N'D:\test_FULL_20110311_050001_1.bak',DISK = N'D:\test_F ...

  9. RabbitMQ 入门 Helloworld -摘自网络

    本系列教程主要来自于官网入门教程的翻译,然后自己进行了部分的修改与实验,内容仅供参考. “Hello world” of RabbitMQ 1.Windows下RabbitMQ的安装 下载Erlang ...

  10. Glibc辅助运行库 (C RunTime Library): crt0.o,crt1.o,crti.o crtn.o,crtbegin.o crtend.o

    crt1.o, crti.o, crtbegin.o, crtend.o, crtn.o 等目标文件和daemon.o(由我们自己的C程序文件产生)链接成一个执行文件.前面这5个目标文件的作用分别是启 ...