①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. .NET之美——C# 中的委托和事件

    C# 中的委托和事件 文中代码在VS2005下通过,由于VS2003(.Net Framework 1.1)不支持隐式的委托变量,所以如果在一个接受委托类型的位置直接赋予方法名,在VS2003下会报错 ...

  2. POJ 2481 Cows

    Cows Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 16546   Accepted: 5531 Description ...

  3. [Everyday Mathematics]20150107

    设 $f\in C^1[a,b]$, $f(a)=0$, 且存在 $\lm>0$, 使得 $$\bex |f'(x)|\leq \lm |f(x)|,\quad \forall\ x\in [a ...

  4. C++ STL算法系列1---count函数

    一.count函数 algorithm头文件定义了一个count的函数,其功能类似于find.这个函数使用一对迭代器和一个值做参数,返回这个值出现次数的统计结果. 编写程序读取一系列int型数据,并将 ...

  5. XSLT 调用java

    XSLT调用JS  http://www.ibm.com/developerworks/cn/xml/tips/x-tipxsltjs/index.htmlXSLT调用JAVA  http://unm ...

  6. JQuery插件的学习

    此前一直想就关于Jquery插件的开发,做一个深入的学习,由于各种原因,当然主要是自己太懒了...今天就系统分析一下Jquery插件的开发(参考了http://www.xprogrammer.com/ ...

  7. 8个很有用的PHP安全函数,你知道几个?

    原文:Useful functions to provide secure PHP application 译文:有用的PHP安全函数 译者:dwqs 安 全是编程非常重要的一个方面.在任何一种编程语 ...

  8. mybatis系列-06-输入映射

    通过parameterType指定输入参数的类型,类型可以是简单类型.hashmap.pojo的包装类型 6.1     传递pojo的包装对象 6.1.1     需求 完成用户信息的综合查询,需要 ...

  9. mysql怎么让一个存储过程定时执行

    比如说每天的12:30执行 查看event是否开启: show variables like '%sche%'; 将事件计划开启: set global event_scheduler=1; 关闭事件 ...

  10. Chapter 2 创建一个应用

    App Engine开发模式如下一般简单<1.The App Engine development model is as simple as it gets:>: 1.创建这个应用 2. ...