C++ STL源代码学习(map,set内部heap篇)
stl_heap.h
///STL中使用的是大顶堆
/// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap.
template <class _RandomAccessIterator, class _Distance, class _Tp>
void
__push_heap(_RandomAccessIterator __first,
_Distance __holeIndex, _Distance __topIndex, _Tp __value)
{
_Distance __parent = (__holeIndex - 1) / 2; ///逐层上溯,查找要插入的位置
while (__holeIndex > __topIndex && *(__first + __parent) < __value) {
*(__first + __holeIndex) = *(__first + __parent);
__holeIndex = __parent;
__parent = (__holeIndex - 1) / 2;
} ///找到位置,插入
*(__first + __holeIndex) = __value;
} template <class _RandomAccessIterator, class _Distance, class _Tp>
inline void
__push_heap_aux(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Distance*, _Tp*)
{
__push_heap(__first, _Distance((__last - __first) - 1), _Distance(0),
_Tp(*(__last - 1)));
} template <class _RandomAccessIterator>
inline void
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
__STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
_LessThanComparable); __push_heap_aux(__first, __last,
__DISTANCE_TYPE(__first), __VALUE_TYPE(__first));
} template <class _RandomAccessIterator, class _Distance, class _Tp,
class _Compare>
void
__push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
_Distance __topIndex, _Tp __value, _Compare __comp)
{
_Distance __parent = (__holeIndex - 1) / 2;
while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) {
*(__first + __holeIndex) = *(__first + __parent);
__holeIndex = __parent;
__parent = (__holeIndex - 1) / 2;
}
*(__first + __holeIndex) = __value;
} template <class _RandomAccessIterator, class _Compare,
class _Distance, class _Tp>
inline void
__push_heap_aux(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp,
_Distance*, _Tp*)
{
__push_heap(__first, _Distance((__last - __first) - 1), _Distance(0),
_Tp(*(__last - 1)), __comp);
} template <class _RandomAccessIterator, class _Compare>
inline void
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
__push_heap_aux(__first, __last, __comp,
__DISTANCE_TYPE(__first), __VALUE_TYPE(__first));
} ///将__holeIndex处的结点摘掉,并保持合法的大顶堆状态,然后插入__value
///运行此函数前,必须保证以__holeIndex为根节点构成的全然二叉树符合大顶堆的定义
template <class _RandomAccessIterator, class _Distance, class _Tp>
void
__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
_Distance __len, _Tp __value)
{
_Distance __topIndex = __holeIndex;
_Distance __secondChild = 2 * __holeIndex + 2;
///向下遍历,从__holeIndex中找出两个孩子中较大的一个填入__holeIndex,并令__holeIndex
///等于该孩子,继续运行,直至__holeIndex无孩子或者仅仅有一个孩子(为了占被摘取的那个节点的位置)
while (__secondChild < __len) {
if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
__secondChild--;
*(__first + __holeIndex) = *(__first + __secondChild);
__holeIndex = __secondChild;
__secondChild = 2 * (__secondChild + 1);
} if (__secondChild == __len) { ///__holeIndex仅仅有一个孩子,补充上去
*(__first + __holeIndex) = *(__first + (__secondChild - 1));
__holeIndex = __secondChild - 1;
} ///至此,大顶堆合法,插入__value
__push_heap(__first, __holeIndex, __topIndex, __value);
} template <class _RandomAccessIterator, class _Tp, class _Distance>
inline void
__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_RandomAccessIterator __result, _Tp __value, _Distance*)
{
///该函数并未删除弹出的那个元素,而仅仅是将它移动到最后面
*__result = *__first;
__adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value);
} template <class _RandomAccessIterator, class _Tp>
inline void
__pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Tp*)
{
__pop_heap(__first, __last - 1, __last - 1,
_Tp(*(__last - 1)), __DISTANCE_TYPE(__first));
} template <class _RandomAccessIterator>
inline void pop_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
__STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
_LessThanComparable); __pop_heap_aux(__first, __last, __VALUE_TYPE(__first));
} template <class _RandomAccessIterator, class _Distance,
class _Tp, class _Compare>
void
__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
_Distance __len, _Tp __value, _Compare __comp)
{
_Distance __topIndex = __holeIndex;
_Distance __secondChild = 2 * __holeIndex + 2;
while (__secondChild < __len) {
if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1))))
__secondChild--;
*(__first + __holeIndex) = *(__first + __secondChild);
__holeIndex = __secondChild;
__secondChild = 2 * (__secondChild + 1);
}
if (__secondChild == __len) {
*(__first + __holeIndex) = *(__first + (__secondChild - 1));
__holeIndex = __secondChild - 1;
}
__push_heap(__first, __holeIndex, __topIndex, __value, __comp);
} template <class _RandomAccessIterator, class _Tp, class _Compare,
class _Distance>
inline void
__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_RandomAccessIterator __result, _Tp __value, _Compare __comp,
_Distance*)
{
*__result = *__first;
__adjust_heap(__first, _Distance(0), _Distance(__last - __first),
__value, __comp);
} template <class _RandomAccessIterator, class _Tp, class _Compare>
inline void
__pop_heap_aux(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Tp*, _Compare __comp)
{
__pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp,
__DISTANCE_TYPE(__first));
} template <class _RandomAccessIterator, class _Compare>
inline void
pop_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
__pop_heap_aux(__first, __last, __VALUE_TYPE(__first), __comp);
} template <class _RandomAccessIterator, class _Tp, class _Distance>
void
__make_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Tp*, _Distance*)
{
if (__last - __first < 2) return;
_Distance __len = __last - __first; ///因为__adjust_heap的要求,必须从最底层開始逐层向上调整.
_Distance __parent = (__len - 2)/2; ///此时它的两个孩子分别为__len-1,len while (true) {
__adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)));
if (__parent == 0) return;
__parent--;
}
} template <class _RandomAccessIterator>
inline void
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
__STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
_LessThanComparable); __make_heap(__first, __last,
__VALUE_TYPE(__first), __DISTANCE_TYPE(__first));
} template <class _RandomAccessIterator, class _Compare,
class _Tp, class _Distance>
void
__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp, _Tp*, _Distance*)
{
if (__last - __first < 2) return;
_Distance __len = __last - __first;
_Distance __parent = (__len - 2)/2; while (true) {
__adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)),
__comp);
if (__parent == 0) return;
__parent--;
}
} template <class _RandomAccessIterator, class _Compare>
inline void
make_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); __make_heap(__first, __last, __comp,
__VALUE_TYPE(__first), __DISTANCE_TYPE(__first));
} template <class _RandomAccessIterator>
void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
__STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
_LessThanComparable); ///因为pop_heap函数并未正真将结点删除,此函数得以实现
while (__last - __first > 1)
pop_heap(__first, __last--);
} template <class _RandomAccessIterator, class _Compare>
void
sort_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
{
__STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
while (__last - __first > 1)
pop_heap(__first, __last--, __comp);
}
C++ STL源代码学习(map,set内部heap篇)的更多相关文章
- C++ STL源代码学习之算法篇
///因为篇幅太长,因此,删去了非常多接口,仅仅分析了内部实现,算法对迭代器的要求也被删去 /// search. template <class _ForwardIter1, class _F ...
- STL源代码学习--vector用法汇总
一.容器vector 使用vector你必须包含头文件<vector>: #include<vector> 型别vector是一个定义于namespace std内的templ ...
- C++ STL源代码学习(list篇)
///STL list为双向循环链表 struct _List_node_base { _List_node_base* _M_next; _List_node_base* _M_prev; }; t ...
- C++ STL 源代码学习(之deque篇)
stl_deque.h /** Class invariants: * For any nonsingular iterator i: * i.node is the address of an el ...
- C++STL源代码学习(之slist篇)
///stl_slist.h ///list为双向循环链表,slist为单向链表.某些操作效率更高 ///slist是SGI额外提供的单向链表,不属于C++标准 struct _Slist_node_ ...
- STL源代码学习(vector篇)
#include <concept_checks.h> #include<stl_allocate.h> /// The vector base class's constru ...
- STL的pair学习, map学习
http://blog.csdn.net/calvin_zcx/article/details/6072286 http://www.linuxidc.com/Linux/2014-10/107621 ...
- STL源代码分析——STL算法sort排序算法
前言 因为在前文的<STL算法剖析>中,源代码剖析许多,不方便学习,也不方便以后复习.这里把这些算法进行归类,对他们单独的源代码剖析进行解说.本文介绍的STL算法中的sort排序算法,SG ...
- STL中关于map和set的四个问题?
STL map和set的使用虽不复杂,但也有一些不易理解的地方,如: 为何map和set的插入删除效率比用其他序列容器高? 或许有得人能回答出来大概原因,但要彻底明白,还需要了解STL的底层数据结构. ...
随机推荐
- 异常:ERROR [org.hibernate.proxy.BasicLazyInitializer] - CGLIB Enhancement failed...
ERROR [org.hibernate.proxy.BasicLazyInitializer] - CGLIB Enhancement failed: com.movie.类 放到lib 包下 \W ...
- 【转】【漫画解读】HDFS存储原理
根据Maneesh Varshney的漫画改编,以简洁易懂的漫画形式讲解HDFS存储机制与运行原理. 一.角色出演 如上图所示,HDFS存储相关角色与功能如下: Client:客户端,系统使用者,调用 ...
- Struts2(五)——核心拦截器
Struts框架一共为我们提供了35个拦截器,其中默认的拦截器有18个,框架访问action的异常处理,配置信息处理,转发重定向选择,上传等等等等,都是这18个拦截器中设置的,起着非比寻常的作用.而这 ...
- Java对象在JVM中的生命周期
当你通过new语句创建一个java对象时,JVM就会为这个对象分配一块内存空间,只要这个对象被引用变量引用了,那么这个对象就会一直驻留在内存中,否则,它就会结束生命周期,JVM会在合适的时 ...
- 心急的C小加(两种解法)
心急的C小加 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 C小加有一些木棒,它们的长度和质量都已经知道,需要一个机器处理这些木棒,机器开启的时候需要耗费一个单位的 ...
- Windows Server 2008 R2 开启Win7主题效果Aero
1.打开 开始---管理工具----服务器管理器--功能 2.点击 “添加功能”,选择“桌面体验”,这样就会安装上win7 主题和Windows media player 3.重启电脑后,在“服务”里 ...
- poj 3216 (最小路径覆盖)
题意:有n个地方,m个任务,每个任务给出地点,开始的时间和完成需要的时间,问最少派多少工人去可以完成所有的任务.给出任意两点直接到达需要的时间,-1代表不能到达. 思路:很明显的最小路径覆盖问题,刚开 ...
- android视频录制、另一部手机实时观看方案
最近调研android视频录制.另一部手机实时观看,大致有以下几种思路. 1. android手机充当服务器,使用NanoHTTPD充当服务器,另一部手机或者pc通过输入http://手机的ip:80 ...
- 自写AES加密解密工具类
此类主要用于加密与解密,采用128位ECB模式,PKCS5Padding填充补位. 可使用方法为加密返回二进制encryptBin(content, key).加密返回十六进制encryptHex(c ...
- php 格式
$abc = ($_POST[' : strtotime($_POST['start_time']); 解析:判断接收的数据是否为0,如果等于0赋值0,若不等于,则赋值获取的数值. strtotime ...