//

//  heap.cpp

//  笔记

//

//  Created by fam on 15/3/15.

//

//

//---------------------------15/03/15----------------------------

//heap

{

/*

heap概述:

heap并不是stl的容器,只是priority queue(优先队列)的助手

它允许用户以任意顺序插入容器,但是取出是,总是取出优先级最高的元素

heap用的是很常见的堆结构,用数组来表示,采用堆排序的方法排序,时刻保持堆的特性

*/

//push_heap

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

{

__push_heap(first,Distance((last - first) -
), Distance(),

T(*(last -
)));

}

template <class RandomAccessIterator,
class Distance, class T>

void __push_heap(RandomAccessIterator first, Distance holeIndex,

Distance topIndex, T value)

{

//取最后一个元素的父节点,先减1的原因是第一个节点时0,

//而不是1开始算的

Distance parent = (holeIndex -
) / ;

//一直循环到当前节点等于根节点
或者 父节点的值大于等于添加的值

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

{

//
把父节点的值赋值给当前节点

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

//当前节点变成父节点

holeIndex = parent;

//父节点变成父节点的父节点

parent = (holeIndex -
) / ;

}

//把值赋值给恰当的位置

*(first + holeIndex) = value;

}

//push功能总结:push就是从最后一个元素开始一直和父节点比较,如果要插入的值(最后一个元素的值)

//比较大就不断上移,直到达到堆的根

//pop_heap

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 -
,last - , T(*(last -
))

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(), Distance(last - first), value);

}

template <class RandomAccessIterator,
class Distance, class T>

void __adjust_heap(RandomAccessIterator first, Distance holeIndex,

Distance len, T value)

{

//topIndex == 0   -->>   topelem == first + 0

Distance topIndex = holeIndex;

//由于从0开始计算
所以右儿子为 2n + 2;

//secondChild
其实也是Index,不是真的值

Distance secondChild =
* holeIndex + ;

//只要右儿子存在就一直循环

while (secondChild < len)

{

//如果有右儿子小于左儿子,secondChild就设置为左儿子

//目的是要让当前节点最后成为2个节点中最大的

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

secondChild--;//为什么不是 --secondChild,这样效率更高

//把当前节点的值设置为secondChild的值

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

//当前节点切换成secondChild节点

holeIndex = secondChild;

//设置secondChild为右儿子

secondChild =
* (secondChild + );

}

//存在左儿子(如果有右儿子就会一直循环,最后只有两种情况,一是当前节点到达叶子节点

//一种情况是没有右儿子,但是有左儿子)

if(secondChild == len)

{

//把左儿子的值赋给当前节点

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

//把当前节点切换成左儿子

holeIndex = secondChild -;

}

//把当初标记的最后的一个节点插入堆中( T(*(last - 1)  )

__push_heap(first, holeIndex, topIndex, value);

/*

总结:把根节点输出到result中
所以就要不断把儿子往上移来填充

填充到最后就会空缺一个节点(下面的往上移动总会有一个空缺的)

所以最后要把最后的一个元素插入到堆前面去,也就是最后空缺的是原先

最后面的位置,那就没影响了

如果空缺的已经是最后的元素了,那就是对已经排序好的堆做排序(最后的元素

已经比父节点大了,会马上排好.

*/

}

//sort

template<class RandomAccessIterator>

void sort_heap(RandomAccessIterator first,

RandomAccessIterator last)

{

)

{

pop_heap(first, last--);

}

}

//结束后就是已经排序好的序列,就不是堆了

//make_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*)

{

//判断边界情况,如果只有一个元素
直接返回

) return;

//len==元素个数

Distance len = last - first;

//parent ==
最后一个元素的父节点

Distance parent = (len -
) / ;

while (true)

{

//一直循环,直到全部排序好,从最后的三角形(最后的元素,父节点,左儿子(如果有的话))

//开始,直到根节点,就调整完毕了

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

)
return ;

parent--;

}

}

}


stl源码剖析 详细学习笔记heap的更多相关文章

  1. stl源码剖析 详细学习笔记 算法总览

    //****************************基本算法***************************** /* stl算法总览,不在stl标准规格的sgi专属算法,都以 *加以标 ...

  2. stl源码剖析 详细学习笔记 hashtable

    //---------------------------15/03/24---------------------------- //hashtable { /* 概述: sgi采用的是开链法完成h ...

  3. stl源码剖析 详细学习笔记 set map

    // //  set map.cpp //  笔记 // //  Created by fam on 15/3/23. // // //---------------------------15/03 ...

  4. stl源码剖析 详细学习笔记 RB_tree (1)

    // //  RB_tree_STL.cpp //  笔记 // //  Created by fam on 15/3/21. // // #include "RB_tree_STL.h&q ...

  5. stl源码剖析 详细学习笔记priority_queue slist

    // //  priority_queue.cpp //  笔记 // //  Created by fam on 15/3/16. // // //------------------------- ...

  6. stl源码剖析 详细学习笔记 空间配置器

    //---------------------------15/04/05---------------------------- /* 空间配置器概述: 1:new操作包含两个阶段操作 1>调 ...

  7. stl源码剖析 详细学习笔记 算法(1)

    //---------------------------15/03/27---------------------------- //算法 { /* 质变算法:会改变操作对象之值 所有的stl算法都 ...

  8. stl源码剖析 详细学习笔记 RB_tree (2)

    //---------------------------15/03/22---------------------------- //一直好奇KeyOfValue是什么,查了下就是一个和仿函数差不多 ...

  9. stl源码剖析 详细学习笔记stack queue

    // //  stack.cpp //  笔记 // //  Created by fam on 15/3/15. // // //---------------------------15/03/1 ...

随机推荐

  1. Oracle EBS INV 挑库发放物料搬运单

    create or replace PROCEDURE XX_TRANSACT_MO_LINE AS -- Common Declarations l_api_version NUMBER := 1. ...

  2. Jboss7或者wildfly部署war包的问题

    如果在Jboss7或者wildfly中部署war包是遇到类似如下错误: "{"JBAS014671: Failed services" => {"jbos ...

  3. 监控文件内容变化,即时写入到新文件(tail)

    监控文件a,如有新内容写入,即时将新内容写入到新文件aa中: fw=open('e:\\aa.txt','ab') with open('e:\\a.txt','rb') as fo: while T ...

  4. MySQL压缩包zip安装

    看了网上好多种教程,自己尝试失败了好多次,最后总算弄好了,具体如下 zip下载地址:https://dev.mysql.com/downloads/mysql/ 之后点击No thanks, just ...

  5. Javaweb学习(三):Servlet程序

    好了,既然开发环境已经配置好了.那么我们首先要搞定得便是servlet了,至于为什么不先去研究jsp,这是因为jsp与servlet本就是一体两面,jsp其本身经过编译.载入.转化等步骤最终会成为se ...

  6. SDN 期末作业验收

    前言 SDN 期末作业验收我们是采用的参考场景一,我们在此场景的基础上来做负载均衡,下面是我们搭建的拓扑图 演示视频 https://pan.baidu.com/s/1htkKLPM 负载均衡程序 相 ...

  7. Spring的InitializingBean与DisposableBean方法

    在bean初始化的时候,将所有显示提供的属性设置完毕后调用这个方法 org.springframework.beans.factory.InitializingBean#afterProperties ...

  8. MYSQL一次千万级连表查询优化(一)

    摘自网上学习之用 https://blog.csdn.net/Tim_phper/article/details/78344444 概述: 交代一下背景,这算是一次项目经验吧,属于公司一个已上线平台的 ...

  9. JVM内存管理及GC机制

    一.概述 Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码,对内存泄露 ...

  10. windows10 + anaconda + tensorflow-1.5.0 + python-3.6 + keras-2.2.4配置和安装

    windows10 + anaconda + tensorflow-1.5.0 + python-3.6 + keras-2.2.4配置和安装 (base) C:\Users\jiangshan> ...