STL中heap算法(堆算法)
①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算法(堆算法)的更多相关文章
- L2-012. 关于堆的判断(STL中heap)
L2-012. 关于堆的判断 将一系列给定数字顺序插入一个初始为空的小顶堆H[].随后判断一系列相关命题是否为真.命题分下列几种: “x is the root”:x是根结点: “x and y ...
- STL中heap相关函数
heap并不是属于STL中的containers,而是在<algorithm>下提供了相关的函数 make_heap,sort_heap,pop_heap,push_heap 函数的说明: ...
- stl中常用的排序算法
#include"iostream" #include"vector" using namespace std; #include"string&qu ...
- java 中 heap(堆)和stack(栈)的区别
总结在Java里面Heap和Stack分别存储数据的不同. 区别项 Heap(堆) Stack(栈) JVM中的功能 内存数据区 内存指令区 存储数据 对象实例(注1) 基本数据类型, 指令代码,常量 ...
- STL中heap用法
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; ]={,, ...
- 论C++STL源代码中关于堆算法的那些事
关于堆,我们肯定熟知的就是它排序的时间复杂度在几个排序算法里面算是比較靠上的O(nlogn)常常会拿来和高速排序和归并排序讨论,并且它还有个长处是它的空间复杂度为O(1), 可是STL中没有给我们提供 ...
- STL源码剖析:算法
启 算法,问题之解法也 算法好坏的衡量标准:时间和空间,单位是对数.一次.二次.三次等 算法中处理的数据,输入方式都是左闭又开,类型就迭代器, 如:[first, last) STL中提供了很多算法, ...
- C++ STL中Map的按Key排序和按Value排序
map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区 分),我们用map来进 ...
- C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET
C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET C++ STL中Map的相关排序操作:按Key排序和按Value排序 分类: C ...
随机推荐
- Ch04-文字列表的设计
Ch04: 文字列表的设计 4.1 编号列表 语法: <OL> <li>编号1 <li>编号2 ...... </OL> 属性: 编号类型:type=1 ...
- Linux如何统计进程的CPU利用率
1.0 概述 在Linux的/proc文件系统,可以看到自启动时候开始,所有CPU消耗的时间片:对于个进程,也可以看到进程消耗的时间片.这是一个累计值,可以"非阻塞"的输出.获得一 ...
- redis发布/订阅模式
其实在很多的MQ产品中都存在这样的一个模式,我们常听到的一个例子 就是邮件订阅的场景,什么意思呢,也就是说100个人订阅了你的博客,如果博主发表了文章,那么100个人就会同时收到通知邮件,除了这个 场 ...
- getView 数据最后加一项
if (position != count-1) { viewHolder.imgLineEnd.setVisibility(View.GONE); } else { viewH ...
- Fitnesse+RestFixture:Web服务回归测试利器
RestFixture是Fitness的一个测试REST服务的插件,用于调用标准的http GET/POST等请求方法,并可以用XPath语法和Javascript语法检验http响应.本文介绍安装运 ...
- 【C# C++】C#中调用msvcr100.dll中的_beginthreadex函数
msvcr100.dll是VS2010的C运行时库DLL, _beginthreadex开启子线程的函数就在这个DLL里面实现 unsigned long _beginthreadex( voi ...
- Java内部类this$0字段产生的一个bug
首先查看下面一段代码,我指出了问题代码的所在,读者先自己思考一下这段代码会有什么问题. 这是用clone方法完整拷贝一个二项堆(BinomialHeap)结构的代码.二项堆中包含一个内部类Binomi ...
- 基于GPL329xx linux平台电容屏gsl1680的驱动调试分析
因客户有用到了gsl1680 7寸电容屏,所以拿了一块过来,便在329xx的平台上面开始调试了. 大概浏览了一下所提供的资料,只有介绍模组的资料跟一份中文版的datasheet,datasheet只是 ...
- SqlHelper 带详细中文注释
using System; using System.Collections.Generic; using System.Linq; using System.Text; //对数据库进行操作引入命名 ...
- Ubuntu中使用pyUSB读取鼠标或键盘的数据程序
参考 :http://www.orangecoat.com/how-to/read-and-decode-data-from-your-mouse-using-this-pyusb-hack 要注意的 ...