00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _CPP_BITS_STL_HEAP_H
00031 #define _CPP_BITS_STL_HEAP_H 1
00032
00033 namespace std
00034 {
00035
00036
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
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
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
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
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
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
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
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
00301 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
00302 _RandomAccessIterator>);
00303
00304 while (__last - __first > 1)
00305 pop_heap(__first, __last--, __comp);
00306 }
00307
00308 }
00309
00310 #endif
00311
00312
00313
00314