stl_heap.h

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 __SGI_STL_INTERNAL_HEAP_H
00031 #define __SGI_STL_INTERNAL_HEAP_H
00032 
00033 __STL_BEGIN_NAMESPACE
00034 
00035 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
00036 #pragma set woff 1209
00037 #endif
00038 
00039 // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap.
00040 
00041 template <class _RandomAccessIterator, class _Distance, class _Tp>
00042 void 
00043 __push_heap(_RandomAccessIterator __first,
00044             _Distance __holeIndex, _Distance __topIndex, _Tp __value)
00045 {
00046   _Distance __parent = (__holeIndex - 1) / 2;
00047   while (__holeIndex > __topIndex && *(__first + __parent) < __value) {
00048     *(__first + __holeIndex) = *(__first + __parent);
00049     __holeIndex = __parent;
00050     __parent = (__holeIndex - 1) / 2;
00051   }    
00052   *(__first + __holeIndex) = __value;
00053 }
00054 
00055 template <class _RandomAccessIterator, class _Distance, class _Tp>
00056 inline void 
00057 __push_heap_aux(_RandomAccessIterator __first,
00058                 _RandomAccessIterator __last, _Distance*, _Tp*)
00059 {
00060   __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), 
00061               _Tp(*(__last - 1)));
00062 }
00063 
00064 template <class _RandomAccessIterator>
00065 inline void 
00066 push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00067 {
00068   __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
00069   __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
00070                  _LessThanComparable);
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   __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
00107   __push_heap_aux(__first, __last, __comp,
00108                   __DISTANCE_TYPE(__first), __VALUE_TYPE(__first));
00109 }
00110 
00111 template <class _RandomAccessIterator, class _Distance, class _Tp>
00112 void 
00113 __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
00114               _Distance __len, _Tp __value)
00115 {
00116   _Distance __topIndex = __holeIndex;
00117   _Distance __secondChild = 2 * __holeIndex + 2;
00118   while (__secondChild < __len) {
00119     if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
00120       __secondChild--;
00121     *(__first + __holeIndex) = *(__first + __secondChild);
00122     __holeIndex = __secondChild;
00123     __secondChild = 2 * (__secondChild + 1);
00124   }
00125   if (__secondChild == __len) {
00126     *(__first + __holeIndex) = *(__first + (__secondChild - 1));
00127     __holeIndex = __secondChild - 1;
00128   }
00129   __push_heap(__first, __holeIndex, __topIndex, __value);
00130 }
00131 
00132 template <class _RandomAccessIterator, class _Tp, class _Distance>
00133 inline void 
00134 __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00135            _RandomAccessIterator __result, _Tp __value, _Distance*)
00136 {
00137   *__result = *__first;
00138   __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value);
00139 }
00140 
00141 template <class _RandomAccessIterator, class _Tp>
00142 inline void 
00143 __pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last,
00144                _Tp*)
00145 {
00146   __pop_heap(__first, __last - 1, __last - 1, 
00147              _Tp(*(__last - 1)), __DISTANCE_TYPE(__first));
00148 }
00149 
00150 template <class _RandomAccessIterator>
00151 inline void pop_heap(_RandomAccessIterator __first, 
00152                      _RandomAccessIterator __last)
00153 {
00154   __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
00155   __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
00156                  _LessThanComparable);
00157   __pop_heap_aux(__first, __last, __VALUE_TYPE(__first));
00158 }
00159 
00160 template <class _RandomAccessIterator, class _Distance,
00161           class _Tp, class _Compare>
00162 void
00163 __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
00164               _Distance __len, _Tp __value, _Compare __comp)
00165 {
00166   _Distance __topIndex = __holeIndex;
00167   _Distance __secondChild = 2 * __holeIndex + 2;
00168   while (__secondChild < __len) {
00169     if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1))))
00170       __secondChild--;
00171     *(__first + __holeIndex) = *(__first + __secondChild);
00172     __holeIndex = __secondChild;
00173     __secondChild = 2 * (__secondChild + 1);
00174   }
00175   if (__secondChild == __len) {
00176     *(__first + __holeIndex) = *(__first + (__secondChild - 1));
00177     __holeIndex = __secondChild - 1;
00178   }
00179   __push_heap(__first, __holeIndex, __topIndex, __value, __comp);
00180 }
00181 
00182 template <class _RandomAccessIterator, class _Tp, class _Compare, 
00183           class _Distance>
00184 inline void 
00185 __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00186            _RandomAccessIterator __result, _Tp __value, _Compare __comp,
00187            _Distance*)
00188 {
00189   *__result = *__first;
00190   __adjust_heap(__first, _Distance(0), _Distance(__last - __first), 
00191                 __value, __comp);
00192 }
00193 
00194 template <class _RandomAccessIterator, class _Tp, class _Compare>
00195 inline void 
00196 __pop_heap_aux(_RandomAccessIterator __first,
00197                _RandomAccessIterator __last, _Tp*, _Compare __comp)
00198 {
00199   __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp,
00200              __DISTANCE_TYPE(__first));
00201 }
00202 
00203 template <class _RandomAccessIterator, class _Compare>
00204 inline void 
00205 pop_heap(_RandomAccessIterator __first,
00206          _RandomAccessIterator __last, _Compare __comp)
00207 {
00208   __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
00209   __pop_heap_aux(__first, __last, __VALUE_TYPE(__first), __comp);
00210 }
00211 
00212 template <class _RandomAccessIterator, class _Tp, class _Distance>
00213 void 
00214 __make_heap(_RandomAccessIterator __first,
00215             _RandomAccessIterator __last, _Tp*, _Distance*)
00216 {
00217   if (__last - __first < 2) return;
00218   _Distance __len = __last - __first;
00219   _Distance __parent = (__len - 2)/2;
00220     
00221   while (true) {
00222     __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)));
00223     if (__parent == 0) return;
00224     __parent--;
00225   }
00226 }
00227 
00228 template <class _RandomAccessIterator>
00229 inline void 
00230 make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00231 {
00232   __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
00233   __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
00234                  _LessThanComparable);
00235   __make_heap(__first, __last,
00236               __VALUE_TYPE(__first), __DISTANCE_TYPE(__first));
00237 }
00238 
00239 template <class _RandomAccessIterator, class _Compare,
00240           class _Tp, class _Distance>
00241 void
00242 __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00243             _Compare __comp, _Tp*, _Distance*)
00244 {
00245   if (__last - __first < 2) return;
00246   _Distance __len = __last - __first;
00247   _Distance __parent = (__len - 2)/2;
00248     
00249   while (true) {
00250     __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)),
00251                   __comp);
00252     if (__parent == 0) return;
00253     __parent--;
00254   }
00255 }
00256 
00257 template <class _RandomAccessIterator, class _Compare>
00258 inline void 
00259 make_heap(_RandomAccessIterator __first, 
00260           _RandomAccessIterator __last, _Compare __comp)
00261 {
00262   __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
00263   __make_heap(__first, __last, __comp,
00264               __VALUE_TYPE(__first), __DISTANCE_TYPE(__first));
00265 }
00266 
00267 template <class _RandomAccessIterator>
00268 void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00269 {
00270   __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
00271   __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type,
00272                  _LessThanComparable);
00273   while (__last - __first > 1)
00274     pop_heap(__first, __last--);
00275 }
00276 
00277 template <class _RandomAccessIterator, class _Compare>
00278 void 
00279 sort_heap(_RandomAccessIterator __first,
00280           _RandomAccessIterator __last, _Compare __comp)
00281 {
00282   __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator);
00283   while (__last - __first > 1)
00284     pop_heap(__first, __last--, __comp);
00285 }
00286 
00287 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
00288 #pragma reset woff 1209
00289 #endif
00290 
00291 __STL_END_NAMESPACE
00292 
00293 #endif /* __SGI_STL_INTERNAL_HEAP_H */
00294 
00295 // Local Variables:
00296 // mode:C++
00297 // End:

Generated on Mon Jun 5 10:20:44 2006 for Intelligence.kdevelop by  doxygen 1.4.6