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

 }

}

最新文章

  1. .NET足球赛事资料数据库平台SmartLottery开源发布——全球足球联赛应有尽有
  2. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【开篇】【持续更新中。。。】
  3. WIN7无法记住远程登录密码
  4. IOS TableView 去除点击后产生的灰色背景
  5. 在Winform开发框架中,利用DevExpress控件实现数据的快速录入和选择
  6. [bzoj 1027][JSOI2007]合金(解析几何+最小环)
  7. BI案例:BI在连锁零售业应用(ZT)【转】
  8. Educational Codeforces Round 4 D. The Union of k-Segments 排序
  9. CyclicBarrier 使用说明
  10. 3.x vector的用法
  11. 【模拟】Codeforces 711A Bus to Udayland
  12. 阳光餐厅--oracle---建表---danrong
  13. redis高级实用特性(2)
  14. Linq to Objects for Java 发布 1.0.1 版本
  15. Leetcode题解(十八)
  16. Spark源码编译,官网学习
  17. eclipse添加market ,maven
  18. 分享一款Markdown的css样式
  19. 中间人攻击工具ettercap
  20. [转]Java GC的原理

热门文章

  1. SQL之50个常用的SQL语句
  2. oracle-Oracle试题
  3. MyBatis 物理分页
  4. Android UI详解之Fragment加载
  5. webdriver(python) 学习笔记三
  6. Survival(ZOJ 2297状压dp)
  7. Linux性能监控之Memory篇
  8. Python多线程和Python的锁
  9. CentOS7 mariadb 修改编码
  10. sql联接那点儿事儿