stl_heap.h

  1. ///STL中使用的是大顶堆
  2. /// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap.
  3. template <class _RandomAccessIterator, class _Distance, class _Tp>
  4. void
  5. __push_heap(_RandomAccessIterator __first,
  6. _Distance __holeIndex, _Distance __topIndex, _Tp __value)
  7. {
  8. _Distance __parent = (__holeIndex - 1) / 2;
  9.  
  10. ///逐层上溯,查找要插入的位置
  11. while (__holeIndex > __topIndex && *(__first + __parent) < __value) {
  12. *(__first + __holeIndex) = *(__first + __parent);
  13. __holeIndex = __parent;
  14. __parent = (__holeIndex - 1) / 2;
  15. }
  16.  
  17. ///找到位置,插入
  18. *(__first + __holeIndex) = __value;
  19. }
  20.  
  21. template <class _RandomAccessIterator, class _Distance, class _Tp>
  22. inline void
  23. __push_heap_aux(_RandomAccessIterator __first,
  24. _RandomAccessIterator __last, _Distance*, _Tp*)
  25. {
  26. __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0),
  27. _Tp(*(__last - 1)));
  28. }
  29.  
  30. template <class _RandomAccessIterator>
  31. inline void
  32. push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
  33. {
  34. __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
  35. __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
  36. _LessThanComparable);
  37.  
  38. __push_heap_aux(__first, __last,
  39. __DISTANCE_TYPE(__first), __VALUE_TYPE(__first));
  40. }
  41.  
  42. template <class _RandomAccessIterator, class _Distance, class _Tp,
  43. class _Compare>
  44. void
  45. __push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
  46. _Distance __topIndex, _Tp __value, _Compare __comp)
  47. {
  48. _Distance __parent = (__holeIndex - 1) / 2;
  49. while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) {
  50. *(__first + __holeIndex) = *(__first + __parent);
  51. __holeIndex = __parent;
  52. __parent = (__holeIndex - 1) / 2;
  53. }
  54. *(__first + __holeIndex) = __value;
  55. }
  56.  
  57. template <class _RandomAccessIterator, class _Compare,
  58. class _Distance, class _Tp>
  59. inline void
  60. __push_heap_aux(_RandomAccessIterator __first,
  61. _RandomAccessIterator __last, _Compare __comp,
  62. _Distance*, _Tp*)
  63. {
  64. __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0),
  65. _Tp(*(__last - 1)), __comp);
  66. }
  67.  
  68. template <class _RandomAccessIterator, class _Compare>
  69. inline void
  70. push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
  71. _Compare __comp)
  72. {
  73. __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
  74. __push_heap_aux(__first, __last, __comp,
  75. __DISTANCE_TYPE(__first), __VALUE_TYPE(__first));
  76. }
  77.  
  78. ///将__holeIndex处的结点摘掉,并保持合法的大顶堆状态,然后插入__value
  79. ///运行此函数前,必须保证以__holeIndex为根节点构成的全然二叉树符合大顶堆的定义
  80. template <class _RandomAccessIterator, class _Distance, class _Tp>
  81. void
  82. __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
  83. _Distance __len, _Tp __value)
  84. {
  85. _Distance __topIndex = __holeIndex;
  86. _Distance __secondChild = 2 * __holeIndex + 2;
  87. ///向下遍历,从__holeIndex中找出两个孩子中较大的一个填入__holeIndex,并令__holeIndex
  88. ///等于该孩子,继续运行,直至__holeIndex无孩子或者仅仅有一个孩子(为了占被摘取的那个节点的位置)
  89. while (__secondChild < __len) {
  90. if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
  91. __secondChild--;
  92. *(__first + __holeIndex) = *(__first + __secondChild);
  93. __holeIndex = __secondChild;
  94. __secondChild = 2 * (__secondChild + 1);
  95. }
  96.  
  97. if (__secondChild == __len) { ///__holeIndex仅仅有一个孩子,补充上去
  98. *(__first + __holeIndex) = *(__first + (__secondChild - 1));
  99. __holeIndex = __secondChild - 1;
  100. }
  101.  
  102. ///至此,大顶堆合法,插入__value
  103. __push_heap(__first, __holeIndex, __topIndex, __value);
  104. }
  105.  
  106. template <class _RandomAccessIterator, class _Tp, class _Distance>
  107. inline void
  108. __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
  109. _RandomAccessIterator __result, _Tp __value, _Distance*)
  110. {
  111. ///该函数并未删除弹出的那个元素,而仅仅是将它移动到最后面
  112. *__result = *__first;
  113. __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value);
  114. }
  115.  
  116. template <class _RandomAccessIterator, class _Tp>
  117. inline void
  118. __pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last,
  119. _Tp*)
  120. {
  121. __pop_heap(__first, __last - 1, __last - 1,
  122. _Tp(*(__last - 1)), __DISTANCE_TYPE(__first));
  123. }
  124.  
  125. template <class _RandomAccessIterator>
  126. inline void pop_heap(_RandomAccessIterator __first,
  127. _RandomAccessIterator __last)
  128. {
  129. __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
  130. __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
  131. _LessThanComparable);
  132.  
  133. __pop_heap_aux(__first, __last, __VALUE_TYPE(__first));
  134. }
  135.  
  136. template <class _RandomAccessIterator, class _Distance,
  137. class _Tp, class _Compare>
  138. void
  139. __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
  140. _Distance __len, _Tp __value, _Compare __comp)
  141. {
  142. _Distance __topIndex = __holeIndex;
  143. _Distance __secondChild = 2 * __holeIndex + 2;
  144. while (__secondChild < __len) {
  145. if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1))))
  146. __secondChild--;
  147. *(__first + __holeIndex) = *(__first + __secondChild);
  148. __holeIndex = __secondChild;
  149. __secondChild = 2 * (__secondChild + 1);
  150. }
  151. if (__secondChild == __len) {
  152. *(__first + __holeIndex) = *(__first + (__secondChild - 1));
  153. __holeIndex = __secondChild - 1;
  154. }
  155. __push_heap(__first, __holeIndex, __topIndex, __value, __comp);
  156. }
  157.  
  158. template <class _RandomAccessIterator, class _Tp, class _Compare,
  159. class _Distance>
  160. inline void
  161. __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
  162. _RandomAccessIterator __result, _Tp __value, _Compare __comp,
  163. _Distance*)
  164. {
  165. *__result = *__first;
  166. __adjust_heap(__first, _Distance(0), _Distance(__last - __first),
  167. __value, __comp);
  168. }
  169.  
  170. template <class _RandomAccessIterator, class _Tp, class _Compare>
  171. inline void
  172. __pop_heap_aux(_RandomAccessIterator __first,
  173. _RandomAccessIterator __last, _Tp*, _Compare __comp)
  174. {
  175. __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp,
  176. __DISTANCE_TYPE(__first));
  177. }
  178.  
  179. template <class _RandomAccessIterator, class _Compare>
  180. inline void
  181. pop_heap(_RandomAccessIterator __first,
  182. _RandomAccessIterator __last, _Compare __comp)
  183. {
  184. __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
  185. __pop_heap_aux(__first, __last, __VALUE_TYPE(__first), __comp);
  186. }
  187.  
  188. template <class _RandomAccessIterator, class _Tp, class _Distance>
  189. void
  190. __make_heap(_RandomAccessIterator __first,
  191. _RandomAccessIterator __last, _Tp*, _Distance*)
  192. {
  193. if (__last - __first < 2) return;
  194. _Distance __len = __last - __first;
  195.  
  196. ///因为__adjust_heap的要求,必须从最底层開始逐层向上调整.
  197. _Distance __parent = (__len - 2)/2; ///此时它的两个孩子分别为__len-1,len
  198.  
  199. while (true) {
  200. __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)));
  201. if (__parent == 0) return;
  202. __parent--;
  203. }
  204. }
  205.  
  206. template <class _RandomAccessIterator>
  207. inline void
  208. make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
  209. {
  210. __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
  211. __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
  212. _LessThanComparable);
  213.  
  214. __make_heap(__first, __last,
  215. __VALUE_TYPE(__first), __DISTANCE_TYPE(__first));
  216. }
  217.  
  218. template <class _RandomAccessIterator, class _Compare,
  219. class _Tp, class _Distance>
  220. void
  221. __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
  222. _Compare __comp, _Tp*, _Distance*)
  223. {
  224. if (__last - __first < 2) return;
  225. _Distance __len = __last - __first;
  226. _Distance __parent = (__len - 2)/2;
  227.  
  228. while (true) {
  229. __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)),
  230. __comp);
  231. if (__parent == 0) return;
  232. __parent--;
  233. }
  234. }
  235.  
  236. template <class _RandomAccessIterator, class _Compare>
  237. inline void
  238. make_heap(_RandomAccessIterator __first,
  239. _RandomAccessIterator __last, _Compare __comp)
  240. {
  241. __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
  242.  
  243. __make_heap(__first, __last, __comp,
  244. __VALUE_TYPE(__first), __DISTANCE_TYPE(__first));
  245. }
  246.  
  247. template <class _RandomAccessIterator>
  248. void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
  249. {
  250. __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
  251. __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
  252. _LessThanComparable);
  253.  
  254. ///因为pop_heap函数并未正真将结点删除,此函数得以实现
  255. while (__last - __first > 1)
  256. pop_heap(__first, __last--);
  257. }
  258.  
  259. template <class _RandomAccessIterator, class _Compare>
  260. void
  261. sort_heap(_RandomAccessIterator __first,
  262. _RandomAccessIterator __last, _Compare __comp)
  263. {
  264. __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
  265. while (__last - __first > 1)
  266. pop_heap(__first, __last--, __comp);
  267. }

C++ STL源代码学习(map,set内部heap篇)的更多相关文章

  1. C++ STL源代码学习之算法篇

    ///因为篇幅太长,因此,删去了非常多接口,仅仅分析了内部实现,算法对迭代器的要求也被删去 /// search. template <class _ForwardIter1, class _F ...

  2. STL源代码学习--vector用法汇总

    一.容器vector 使用vector你必须包含头文件<vector>: #include<vector> 型别vector是一个定义于namespace std内的templ ...

  3. C++ STL源代码学习(list篇)

    ///STL list为双向循环链表 struct _List_node_base { _List_node_base* _M_next; _List_node_base* _M_prev; }; t ...

  4. C++ STL 源代码学习(之deque篇)

    stl_deque.h /** Class invariants: * For any nonsingular iterator i: * i.node is the address of an el ...

  5. C++STL源代码学习(之slist篇)

    ///stl_slist.h ///list为双向循环链表,slist为单向链表.某些操作效率更高 ///slist是SGI额外提供的单向链表,不属于C++标准 struct _Slist_node_ ...

  6. STL源代码学习(vector篇)

    #include <concept_checks.h> #include<stl_allocate.h> /// The vector base class's constru ...

  7. STL的pair学习, map学习

    http://blog.csdn.net/calvin_zcx/article/details/6072286 http://www.linuxidc.com/Linux/2014-10/107621 ...

  8. STL源代码分析——STL算法sort排序算法

    前言 因为在前文的<STL算法剖析>中,源代码剖析许多,不方便学习,也不方便以后复习.这里把这些算法进行归类,对他们单独的源代码剖析进行解说.本文介绍的STL算法中的sort排序算法,SG ...

  9. STL中关于map和set的四个问题?

    STL map和set的使用虽不复杂,但也有一些不易理解的地方,如: 为何map和set的插入删除效率比用其他序列容器高? 或许有得人能回答出来大概原因,但要彻底明白,还需要了解STL的底层数据结构. ...

随机推荐

  1. Linux MySql安装步骤

    本文将以MySQL 5.5.47为例,以CentOS 6.5为平台,讲述MySQL数据库的安装和设置. 源码包方式安装 1.新建MySql用户和用户组 groupadd mysql useradd - ...

  2. jquery 绑定动态元素

    以一个小例子来简单说明下情况 ? 1 2 3 4 5 6 7 8  <script src="jquery-1.11.0.min.js"></script> ...

  3. .net项目中上传大图片失败

    .net项目中有时用户提出要上传大图片,一张图片有可能十几兆,本来用的第三方的上传控件,有限制图片上传大小的设置,以前设置的是2M.按照用户的要求,以为直接将限制图片上传大小的设置改下就可以了,但是当 ...

  4. struct2-json

    一.JSON是什么? :JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写,同时也易于机器解 析和生成.它基于JavaScript(Stan ...

  5. 精讲N皇后问题

             思想:存三个数组记录记录走的过程,运用回溯不符合或row==n+1就跳出当前层,直到找完:递归时的路径都在保存着,当连续跳出到第一次进入的dfs且i=n时就全部跳出dfs函数了: # ...

  6. java web分页查询初试

    ssh2分页查询初试,放着记录学习一下. entity:student.java: package com.zte.entity; /** * 数据持久化,跟数据库的的相应的表的字段是对应的. * * ...

  7. Keepalived+Lvs+Mysql主主复制

    一简单介绍 Keepalived+lvs+mysql主主复制是比較经常使用的一种Mysql高可用方案,当中lvs 提供读负载均衡,Keepalived通过虚拟vip漂移实现故障自己主动转移,而Mysq ...

  8. lua 类实现

    Class={}; Class.classList={}; --保存所有已经定义过的类 --类的类型: 类和接口, 接口也是一种类 Class.TYPE_CLASS="Class" ...

  9. 【计算几何初步-凸包-Graham扫描法-极角序】【HDU1348】 WALL

    Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  10. stack 集合栈计算机 (摘)

    有一个专门为了集合运算而设计的“集合栈”计算机.该机器有一个初始为空的栈,并且支持以下操作:PUSH:空集“{}”入栈DUP:把当前栈顶元素复制一份后再入栈UNION:出栈两个集合,然后把两者的并集入 ...