stl_heap.h
上传用户:sichengcw
上传日期:2009-02-17
资源大小:202k
文件大小:8k
源码类别:

STL

开发平台:

Visual C++

  1. /*
  2.  *
  3.  * Copyright (c) 1994
  4.  * Hewlett-Packard Company
  5.  *
  6.  * Permission to use, copy, modify, distribute and sell this software
  7.  * and its documentation for any purpose is hereby granted without fee,
  8.  * provided that the above copyright notice appear in all copies and
  9.  * that both that copyright notice and this permission notice appear
  10.  * in supporting documentation.  Hewlett-Packard Company makes no
  11.  * representations about the suitability of this software for any
  12.  * purpose.  It is provided "as is" without express or implied warranty.
  13.  *
  14.  * Copyright (c) 1997
  15.  * Silicon Graphics Computer Systems, Inc.
  16.  *
  17.  * Permission to use, copy, modify, distribute and sell this software
  18.  * and its documentation for any purpose is hereby granted without fee,
  19.  * provided that the above copyright notice appear in all copies and
  20.  * that both that copyright notice and this permission notice appear
  21.  * in supporting documentation.  Silicon Graphics makes no
  22.  * representations about the suitability of this software for any
  23.  * purpose.  It is provided "as is" without express or implied warranty.
  24.  */
  25. /* NOTE: This is an internal header file, included by other STL headers.
  26.  *   You should not attempt to use it directly.
  27.  */
  28. #ifndef __SGI_STL_INTERNAL_HEAP_H
  29. #define __SGI_STL_INTERNAL_HEAP_H
  30. __STL_BEGIN_NAMESPACE
  31. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  32. #pragma set woff 1209
  33. #endif
  34. template <class RandomAccessIterator, class Distance, class T>
  35. void __push_heap(RandomAccessIterator first, Distance holeIndex,
  36.                  Distance topIndex, T value) {
  37.   Distance parent = (holeIndex - 1) / 2;
  38.   while (holeIndex > topIndex && *(first + parent) < value) {
  39.     *(first + holeIndex) = *(first + parent);
  40.     holeIndex = parent;
  41.     parent = (holeIndex - 1) / 2;
  42.   }    
  43.   *(first + holeIndex) = value;
  44. }
  45. template <class RandomAccessIterator, class Distance, class T>
  46. inline void __push_heap_aux(RandomAccessIterator first,
  47.                             RandomAccessIterator last, Distance*, T*) {
  48.   __push_heap(first, Distance((last - first) - 1), Distance(0), 
  49.               T(*(last - 1)));
  50. }
  51. template <class RandomAccessIterator>
  52. inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) {
  53.   __push_heap_aux(first, last, distance_type(first), value_type(first));
  54. }
  55. template <class RandomAccessIterator, class Distance, class T, class Compare>
  56. void __push_heap(RandomAccessIterator first, Distance holeIndex,
  57.                  Distance topIndex, T value, Compare comp) {
  58.   Distance parent = (holeIndex - 1) / 2;
  59.   while (holeIndex > topIndex && comp(*(first + parent), value)) {
  60.     *(first + holeIndex) = *(first + parent);
  61.     holeIndex = parent;
  62.     parent = (holeIndex - 1) / 2;
  63.   }
  64.   *(first + holeIndex) = value;
  65. }
  66. template <class RandomAccessIterator, class Compare, class Distance, class T>
  67. inline void __push_heap_aux(RandomAccessIterator first,
  68.                             RandomAccessIterator last, Compare comp,
  69.                             Distance*, T*) {
  70.   __push_heap(first, Distance((last - first) - 1), Distance(0), 
  71.               T(*(last - 1)), comp);
  72. }
  73. template <class RandomAccessIterator, class Compare>
  74. inline void push_heap(RandomAccessIterator first, RandomAccessIterator last,
  75.                       Compare comp) {
  76.   __push_heap_aux(first, last, comp, distance_type(first), value_type(first));
  77. }
  78. template <class RandomAccessIterator, class Distance, class T>
  79. void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
  80.                    Distance len, T value) {
  81.   Distance topIndex = holeIndex;
  82.   Distance secondChild = 2 * holeIndex + 2;
  83.   while (secondChild < len) {
  84.     if (*(first + secondChild) < *(first + (secondChild - 1)))
  85.       secondChild--;
  86.     *(first + holeIndex) = *(first + secondChild);
  87.     holeIndex = secondChild;
  88.     secondChild = 2 * (secondChild + 1);
  89.   }
  90.   if (secondChild == len) {
  91.     *(first + holeIndex) = *(first + (secondChild - 1));
  92.     holeIndex = secondChild - 1;
  93.   }
  94.   __push_heap(first, holeIndex, topIndex, value);
  95. }
  96. template <class RandomAccessIterator, class T, class Distance>
  97. inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
  98.                        RandomAccessIterator result, T value, Distance*) {
  99.   *result = *first;
  100.   __adjust_heap(first, Distance(0), Distance(last - first), value);
  101. }
  102. template <class RandomAccessIterator, class T>
  103. inline void __pop_heap_aux(RandomAccessIterator first,
  104.                            RandomAccessIterator last, T*) {
  105.   __pop_heap(first, last - 1, last - 1, T(*(last - 1)), distance_type(first));
  106. }
  107. template <class RandomAccessIterator>
  108. inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) {
  109.   __pop_heap_aux(first, last, value_type(first));
  110. }
  111. template <class RandomAccessIterator, class Distance, class T, class Compare>
  112. void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
  113.                    Distance len, T value, Compare comp) {
  114.   Distance topIndex = holeIndex;
  115.   Distance secondChild = 2 * holeIndex + 2;
  116.   while (secondChild < len) {
  117.     if (comp(*(first + secondChild), *(first + (secondChild - 1))))
  118.       secondChild--;
  119.     *(first + holeIndex) = *(first + secondChild);
  120.     holeIndex = secondChild;
  121.     secondChild = 2 * (secondChild + 1);
  122.   }
  123.   if (secondChild == len) {
  124.     *(first + holeIndex) = *(first + (secondChild - 1));
  125.     holeIndex = secondChild - 1;
  126.   }
  127.   __push_heap(first, holeIndex, topIndex, value, comp);
  128. }
  129. template <class RandomAccessIterator, class T, class Compare, class Distance>
  130. inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
  131.                        RandomAccessIterator result, T value, Compare comp,
  132.                        Distance*) {
  133.   *result = *first;
  134.   __adjust_heap(first, Distance(0), Distance(last - first), value, comp);
  135. }
  136. template <class RandomAccessIterator, class T, class Compare>
  137. inline void __pop_heap_aux(RandomAccessIterator first,
  138.                            RandomAccessIterator last, T*, Compare comp) {
  139.   __pop_heap(first, last - 1, last - 1, T(*(last - 1)), comp,
  140.              distance_type(first));
  141. }
  142. template <class RandomAccessIterator, class Compare>
  143. inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last,
  144.                      Compare comp) {
  145.     __pop_heap_aux(first, last, value_type(first), comp);
  146. }
  147. template <class RandomAccessIterator, class T, class Distance>
  148. void __make_heap(RandomAccessIterator first, RandomAccessIterator last, T*,
  149.                  Distance*) {
  150.   if (last - first < 2) return;
  151.   Distance len = last - first;
  152.   Distance parent = (len - 2)/2;
  153.     
  154.   while (true) {
  155.     __adjust_heap(first, parent, len, T(*(first + parent)));
  156.     if (parent == 0) return;
  157.     parent--;
  158.   }
  159. }
  160. template <class RandomAccessIterator>
  161. inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) {
  162.   __make_heap(first, last, value_type(first), distance_type(first));
  163. }
  164. template <class RandomAccessIterator, class Compare, class T, class Distance>
  165. void __make_heap(RandomAccessIterator first, RandomAccessIterator last,
  166.                  Compare comp, T*, Distance*) {
  167.   if (last - first < 2) return;
  168.   Distance len = last - first;
  169.   Distance parent = (len - 2)/2;
  170.     
  171.   while (true) {
  172.     __adjust_heap(first, parent, len, T(*(first + parent)), comp);
  173.     if (parent == 0) return;
  174.     parent--;
  175.   }
  176. }
  177. template <class RandomAccessIterator, class Compare>
  178. inline void make_heap(RandomAccessIterator first, RandomAccessIterator last,
  179.                       Compare comp) {
  180.   __make_heap(first, last, comp, value_type(first), distance_type(first));
  181. }
  182. template <class RandomAccessIterator>
  183. void sort_heap(RandomAccessIterator first, RandomAccessIterator last) {
  184.   while (last - first > 1) pop_heap(first, last--);
  185. }
  186. template <class RandomAccessIterator, class Compare>
  187. void sort_heap(RandomAccessIterator first, RandomAccessIterator last,
  188.                Compare comp) {
  189.   while (last - first > 1) pop_heap(first, last--, comp);
  190. }
  191. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  192. #pragma reset woff 1209
  193. #endif
  194. __STL_END_NAMESPACE
  195. #endif /* __SGI_STL_INTERNAL_HEAP_H */
  196. // Local Variables:
  197. // mode:C++
  198. // End: