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的底层数据结构. ...
随机推荐
- Linux MySql安装步骤
本文将以MySQL 5.5.47为例,以CentOS 6.5为平台,讲述MySQL数据库的安装和设置. 源码包方式安装 1.新建MySql用户和用户组 groupadd mysql useradd - ...
- jquery 绑定动态元素
以一个小例子来简单说明下情况 ? 1 2 3 4 5 6 7 8 <script src="jquery-1.11.0.min.js"></script> ...
- .net项目中上传大图片失败
.net项目中有时用户提出要上传大图片,一张图片有可能十几兆,本来用的第三方的上传控件,有限制图片上传大小的设置,以前设置的是2M.按照用户的要求,以为直接将限制图片上传大小的设置改下就可以了,但是当 ...
- struct2-json
一.JSON是什么? :JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写,同时也易于机器解 析和生成.它基于JavaScript(Stan ...
- 精讲N皇后问题
思想:存三个数组记录记录走的过程,运用回溯不符合或row==n+1就跳出当前层,直到找完:递归时的路径都在保存着,当连续跳出到第一次进入的dfs且i=n时就全部跳出dfs函数了: # ...
- java web分页查询初试
ssh2分页查询初试,放着记录学习一下. entity:student.java: package com.zte.entity; /** * 数据持久化,跟数据库的的相应的表的字段是对应的. * * ...
- Keepalived+Lvs+Mysql主主复制
一简单介绍 Keepalived+lvs+mysql主主复制是比較经常使用的一种Mysql高可用方案,当中lvs 提供读负载均衡,Keepalived通过虚拟vip漂移实现故障自己主动转移,而Mysq ...
- lua 类实现
Class={}; Class.classList={}; --保存所有已经定义过的类 --类的类型: 类和接口, 接口也是一种类 Class.TYPE_CLASS="Class" ...
- 【计算几何初步-凸包-Graham扫描法-极角序】【HDU1348】 WALL
Wall Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- stack 集合栈计算机 (摘)
有一个专门为了集合运算而设计的“集合栈”计算机.该机器有一个初始为空的栈,并且支持以下操作:PUSH:空集“{}”入栈DUP:把当前栈顶元素复制一份后再入栈UNION:出栈两个集合,然后把两者的并集入 ...