Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

stl_heap.h

Go to the documentation of this file.
00001 /*
00002  *
00003  * Copyright (c) 1994
00004  * Hewlett-Packard Company
00005  *
00006  * Permission to use, copy, modify, distribute and sell this software
00007  * and its documentation for any purpose is hereby granted without fee,
00008  * provided that the above copyright notice appear in all copies and
00009  * that both that copyright notice and this permission notice appear
00010  * in supporting documentation.  Hewlett-Packard Company makes no
00011  * representations about the suitability of this software for any
00012  * purpose.  It is provided "as is" without express or implied warranty.
00013  *
00014  * Copyright (c) 1997
00015  * Silicon Graphics Computer Systems, Inc.
00016  *
00017  * Permission to use, copy, modify, distribute and sell this software
00018  * and its documentation for any purpose is hereby granted without fee,
00019  * provided that the above copyright notice appear in all copies and
00020  * that both that copyright notice and this permission notice appear
00021  * in supporting documentation.  Silicon Graphics makes no
00022  * representations about the suitability of this software for any
00023  * purpose.  It is provided "as is" without express or implied warranty.
00024  */
00025 
00026 /* NOTE: This is an internal header file, included by other STL headers.
00027  *   You should not attempt to use it directly.
00028  */
00029 
00030 #ifndef _CPP_BITS_STL_HEAP_H
00031 #define _CPP_BITS_STL_HEAP_H 1
00032 
00033 namespace std
00034 {
00035 
00036 // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap.
00037 
00038 template <class _RandomAccessIterator, class _Distance, class _Tp>
00039 void 
00040 __push_heap(_RandomAccessIterator __first,
00041             _Distance __holeIndex, _Distance __topIndex, _Tp __value)
00042 {
00043   _Distance __parent = (__holeIndex - 1) / 2;
00044   while (__holeIndex > __topIndex && *(__first + __parent) < __value) {
00045     *(__first + __holeIndex) = *(__first + __parent);
00046     __holeIndex = __parent;
00047     __parent = (__holeIndex - 1) / 2;
00048   }    
00049   *(__first + __holeIndex) = __value;
00050 }
00051 
00052 template <class _RandomAccessIterator, class _Distance, class _Tp>
00053 inline void 
00054 __push_heap_aux(_RandomAccessIterator __first,
00055                 _RandomAccessIterator __last, _Distance*, _Tp*)
00056 {
00057   __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), 
00058               _Tp(*(__last - 1)));
00059 }
00060 
00061 template <class _RandomAccessIterator>
00062 inline void 
00063 push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00064 {
00065   // concept requirements
00066   __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
00067         _RandomAccessIterator>);
00068   __glibcpp_function_requires(_LessThanComparableConcept<
00069         typename iterator_traits<_RandomAccessIterator>::value_type>);
00070 
00071   __push_heap_aux(__first, __last,
00072                   __distance_type(__first), __value_type(__first));
00073 }
00074 
00075 template <class _RandomAccessIterator, class _Distance, class _Tp, 
00076           class _Compare>
00077 void
00078 __push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
00079             _Distance __topIndex, _Tp __value, _Compare __comp)
00080 {
00081   _Distance __parent = (__holeIndex - 1) / 2;
00082   while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) {
00083     *(__first + __holeIndex) = *(__first + __parent);
00084     __holeIndex = __parent;
00085     __parent = (__holeIndex - 1) / 2;
00086   }
00087   *(__first + __holeIndex) = __value;
00088 }
00089 
00090 template <class _RandomAccessIterator, class _Compare,
00091           class _Distance, class _Tp>
00092 inline void 
00093 __push_heap_aux(_RandomAccessIterator __first,
00094                 _RandomAccessIterator __last, _Compare __comp,
00095                 _Distance*, _Tp*) 
00096 {
00097   __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), 
00098               _Tp(*(__last - 1)), __comp);
00099 }
00100 
00101 template <class _RandomAccessIterator, class _Compare>
00102 inline void 
00103 push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00104           _Compare __comp)
00105 {
00106   // concept requirements
00107   __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
00108         _RandomAccessIterator>);
00109 
00110   __push_heap_aux(__first, __last, __comp,
00111                   __distance_type(__first), __value_type(__first));
00112 }
00113 
00114 template <class _RandomAccessIterator, class _Distance, class _Tp>
00115 void 
00116 __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
00117               _Distance __len, _Tp __value)
00118 {
00119   _Distance __topIndex = __holeIndex;
00120   _Distance __secondChild = 2 * __holeIndex + 2;
00121   while (__secondChild < __len) {
00122     if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
00123       __secondChild--;
00124     *(__first + __holeIndex) = *(__first + __secondChild);
00125     __holeIndex = __secondChild;
00126     __secondChild = 2 * (__secondChild + 1);
00127   }
00128   if (__secondChild == __len) {
00129     *(__first + __holeIndex) = *(__first + (__secondChild - 1));
00130     __holeIndex = __secondChild - 1;
00131   }
00132   __push_heap(__first, __holeIndex, __topIndex, __value);
00133 }
00134 
00135 template <class _RandomAccessIterator, class _Tp, class _Distance>
00136 inline void 
00137 __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00138            _RandomAccessIterator __result, _Tp __value, _Distance*)
00139 {
00140   *__result = *__first;
00141   __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value);
00142 }
00143 
00144 template <class _RandomAccessIterator, class _Tp>
00145 inline void 
00146 __pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last,
00147                _Tp*)
00148 {
00149   __pop_heap(__first, __last - 1, __last - 1, 
00150              _Tp(*(__last - 1)), __distance_type(__first));
00151 }
00152 
00153 template <class _RandomAccessIterator>
00154 inline void pop_heap(_RandomAccessIterator __first, 
00155                      _RandomAccessIterator __last)
00156 {
00157   // concept requirements
00158   __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
00159         _RandomAccessIterator>);
00160   __glibcpp_function_requires(_LessThanComparableConcept<
00161         typename iterator_traits<_RandomAccessIterator>::value_type>);
00162 
00163   __pop_heap_aux(__first, __last, __value_type(__first));
00164 }
00165 
00166 template <class _RandomAccessIterator, class _Distance,
00167           class _Tp, class _Compare>
00168 void
00169 __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
00170               _Distance __len, _Tp __value, _Compare __comp)
00171 {
00172   _Distance __topIndex = __holeIndex;
00173   _Distance __secondChild = 2 * __holeIndex + 2;
00174   while (__secondChild < __len) {
00175     if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1))))
00176       __secondChild--;
00177     *(__first + __holeIndex) = *(__first + __secondChild);
00178     __holeIndex = __secondChild;
00179     __secondChild = 2 * (__secondChild + 1);
00180   }
00181   if (__secondChild == __len) {
00182     *(__first + __holeIndex) = *(__first + (__secondChild - 1));
00183     __holeIndex = __secondChild - 1;
00184   }
00185   __push_heap(__first, __holeIndex, __topIndex, __value, __comp);
00186 }
00187 
00188 template <class _RandomAccessIterator, class _Tp, class _Compare, 
00189           class _Distance>
00190 inline void 
00191 __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00192            _RandomAccessIterator __result, _Tp __value, _Compare __comp,
00193            _Distance*)
00194 {
00195   *__result = *__first;
00196   __adjust_heap(__first, _Distance(0), _Distance(__last - __first), 
00197                 __value, __comp);
00198 }
00199 
00200 template <class _RandomAccessIterator, class _Tp, class _Compare>
00201 inline void 
00202 __pop_heap_aux(_RandomAccessIterator __first,
00203                _RandomAccessIterator __last, _Tp*, _Compare __comp)
00204 {
00205   __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp,
00206              __distance_type(__first));
00207 }
00208 
00209 template <class _RandomAccessIterator, class _Compare>
00210 inline void 
00211 pop_heap(_RandomAccessIterator __first,
00212          _RandomAccessIterator __last, _Compare __comp)
00213 {
00214   // concept requirements
00215   __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
00216         _RandomAccessIterator>);
00217 
00218   __pop_heap_aux(__first, __last, __value_type(__first), __comp);
00219 }
00220 
00221 template <class _RandomAccessIterator, class _Tp, class _Distance>
00222 void 
00223 __make_heap(_RandomAccessIterator __first,
00224             _RandomAccessIterator __last, _Tp*, _Distance*)
00225 {
00226   if (__last - __first < 2) return;
00227   _Distance __len = __last - __first;
00228   _Distance __parent = (__len - 2)/2;
00229     
00230   while (true) {
00231     __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)));
00232     if (__parent == 0) return;
00233     __parent--;
00234   }
00235 }
00236 
00237 template <class _RandomAccessIterator>
00238 inline void 
00239 make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00240 {
00241   // concept requirements
00242   __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
00243         _RandomAccessIterator>);
00244   __glibcpp_function_requires(_LessThanComparableConcept<
00245         typename iterator_traits<_RandomAccessIterator>::value_type>);
00246 
00247   __make_heap(__first, __last,
00248               __value_type(__first), __distance_type(__first));
00249 }
00250 
00251 template <class _RandomAccessIterator, class _Compare,
00252           class _Tp, class _Distance>
00253 void
00254 __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00255             _Compare __comp, _Tp*, _Distance*)
00256 {
00257   if (__last - __first < 2) return;
00258   _Distance __len = __last - __first;
00259   _Distance __parent = (__len - 2)/2;
00260     
00261   while (true) {
00262     __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)),
00263                   __comp);
00264     if (__parent == 0) return;
00265     __parent--;
00266   }
00267 }
00268 
00269 template <class _RandomAccessIterator, class _Compare>
00270 inline void 
00271 make_heap(_RandomAccessIterator __first, 
00272           _RandomAccessIterator __last, _Compare __comp)
00273 {
00274   // concept requirements
00275   __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
00276         _RandomAccessIterator>);
00277 
00278   __make_heap(__first, __last, __comp,
00279               __value_type(__first), __distance_type(__first));
00280 }
00281 
00282 template <class _RandomAccessIterator>
00283 void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00284 {
00285   // concept requirements
00286   __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
00287         _RandomAccessIterator>);
00288   __glibcpp_function_requires(_LessThanComparableConcept<
00289         typename iterator_traits<_RandomAccessIterator>::value_type>);
00290 
00291   while (__last - __first > 1)
00292     pop_heap(__first, __last--);
00293 }
00294 
00295 template <class _RandomAccessIterator, class _Compare>
00296 void 
00297 sort_heap(_RandomAccessIterator __first,
00298           _RandomAccessIterator __last, _Compare __comp)
00299 {
00300   // concept requirements
00301   __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
00302         _RandomAccessIterator>);
00303 
00304   while (__last - __first > 1)
00305     pop_heap(__first, __last--, __comp);
00306 }
00307 
00308 } // namespace std
00309 
00310 #endif /* _CPP_BITS_STL_HEAP_H */
00311 
00312 // Local Variables:
00313 // mode:C++
00314 // End:

Generated at Tue May 1 16:28:39 2001 for libstdc++-v3 by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001