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
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #ifndef _STL_HEAP_H
00061 #define _STL_HEAP_H 1
00062
00063 #include <debug/debug.h>
00064
00065 namespace std
00066 {
00067
00068
00069
00070 template<typename _RandomAccessIterator, typename _Distance>
00071 bool
00072 __is_heap(_RandomAccessIterator __first, _Distance __n)
00073 {
00074 _Distance __parent = 0;
00075 for (_Distance __child = 1; __child < __n; ++__child)
00076 {
00077 if (__first[__parent] < __first[__child])
00078 return false;
00079 if ((__child & 1) == 0)
00080 ++__parent;
00081 }
00082 return true;
00083 }
00084
00085 template<typename _RandomAccessIterator, typename _Distance,
00086 typename _StrictWeakOrdering>
00087 bool
00088 __is_heap(_RandomAccessIterator __first, _StrictWeakOrdering __comp,
00089 _Distance __n)
00090 {
00091 _Distance __parent = 0;
00092 for (_Distance __child = 1; __child < __n; ++__child)
00093 {
00094 if (__comp(__first[__parent], __first[__child]))
00095 return false;
00096 if ((__child & 1) == 0)
00097 ++__parent;
00098 }
00099 return true;
00100 }
00101
00102 template<typename _RandomAccessIterator>
00103 bool
00104 __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00105 { return std::__is_heap(__first, std::distance(__first, __last)); }
00106
00107 template<typename _RandomAccessIterator, typename _StrictWeakOrdering>
00108 bool
00109 __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00110 _StrictWeakOrdering __comp)
00111 { return std::__is_heap(__first, __comp, std::distance(__first, __last)); }
00112
00113
00114
00115 template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
00116 void
00117 __push_heap(_RandomAccessIterator __first,
00118 _Distance __holeIndex, _Distance __topIndex, _Tp __value)
00119 {
00120 _Distance __parent = (__holeIndex - 1) / 2;
00121 while (__holeIndex > __topIndex && *(__first + __parent) < __value)
00122 {
00123 *(__first + __holeIndex) = *(__first + __parent);
00124 __holeIndex = __parent;
00125 __parent = (__holeIndex - 1) / 2;
00126 }
00127 *(__first + __holeIndex) = __value;
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 template<typename _RandomAccessIterator>
00140 inline void
00141 push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00142 {
00143 typedef typename iterator_traits<_RandomAccessIterator>::value_type
00144 _ValueType;
00145 typedef typename iterator_traits<_RandomAccessIterator>::difference_type
00146 _DistanceType;
00147
00148
00149 __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00150 _RandomAccessIterator>)
00151 __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
00152 __glibcxx_requires_valid_range(__first, __last);
00153
00154
00155 std::__push_heap(__first, _DistanceType((__last - __first) - 1),
00156 _DistanceType(0), _ValueType(*(__last - 1)));
00157 }
00158
00159 template<typename _RandomAccessIterator, typename _Distance, typename _Tp,
00160 typename _Compare>
00161 void
00162 __push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
00163 _Distance __topIndex, _Tp __value, _Compare __comp)
00164 {
00165 _Distance __parent = (__holeIndex - 1) / 2;
00166 while (__holeIndex > __topIndex
00167 && __comp(*(__first + __parent), __value))
00168 {
00169 *(__first + __holeIndex) = *(__first + __parent);
00170 __holeIndex = __parent;
00171 __parent = (__holeIndex - 1) / 2;
00172 }
00173 *(__first + __holeIndex) = __value;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 template<typename _RandomAccessIterator, typename _Compare>
00188 inline void
00189 push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00190 _Compare __comp)
00191 {
00192 typedef typename iterator_traits<_RandomAccessIterator>::value_type
00193 _ValueType;
00194 typedef typename iterator_traits<_RandomAccessIterator>::difference_type
00195 _DistanceType;
00196
00197
00198 __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00199 _RandomAccessIterator>)
00200 __glibcxx_requires_valid_range(__first, __last);
00201 __glibcxx_requires_heap_pred(__first, __last - 1, __comp);
00202
00203 std::__push_heap(__first, _DistanceType((__last - __first) - 1),
00204 _DistanceType(0), _ValueType(*(__last - 1)), __comp);
00205 }
00206
00207 template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
00208 void
00209 __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
00210 _Distance __len, _Tp __value)
00211 {
00212 const _Distance __topIndex = __holeIndex;
00213 _Distance __secondChild = 2 * __holeIndex + 2;
00214 while (__secondChild < __len)
00215 {
00216 if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
00217 __secondChild--;
00218 *(__first + __holeIndex) = *(__first + __secondChild);
00219 __holeIndex = __secondChild;
00220 __secondChild = 2 * (__secondChild + 1);
00221 }
00222 if (__secondChild == __len)
00223 {
00224 *(__first + __holeIndex) = *(__first + (__secondChild - 1));
00225 __holeIndex = __secondChild - 1;
00226 }
00227 std::__push_heap(__first, __holeIndex, __topIndex, __value);
00228 }
00229
00230 template<typename _RandomAccessIterator, typename _Tp>
00231 inline void
00232 __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00233 _RandomAccessIterator __result, _Tp __value)
00234 {
00235 typedef typename iterator_traits<_RandomAccessIterator>::difference_type
00236 _Distance;
00237 *__result = *__first;
00238 std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first),
00239 __value);
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 template<typename _RandomAccessIterator>
00252 inline void
00253 pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00254 {
00255 typedef typename iterator_traits<_RandomAccessIterator>::value_type
00256 _ValueType;
00257
00258
00259 __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00260 _RandomAccessIterator>)
00261 __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
00262 __glibcxx_requires_valid_range(__first, __last);
00263 __glibcxx_requires_heap(__first, __last);
00264
00265 std::__pop_heap(__first, __last - 1, __last - 1,
00266 _ValueType(*(__last - 1)));
00267 }
00268
00269 template<typename _RandomAccessIterator, typename _Distance,
00270 typename _Tp, typename _Compare>
00271 void
00272 __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
00273 _Distance __len, _Tp __value, _Compare __comp)
00274 {
00275 const _Distance __topIndex = __holeIndex;
00276 _Distance __secondChild = 2 * __holeIndex + 2;
00277 while (__secondChild < __len)
00278 {
00279 if (__comp(*(__first + __secondChild),
00280 *(__first + (__secondChild - 1))))
00281 __secondChild--;
00282 *(__first + __holeIndex) = *(__first + __secondChild);
00283 __holeIndex = __secondChild;
00284 __secondChild = 2 * (__secondChild + 1);
00285 }
00286 if (__secondChild == __len)
00287 {
00288 *(__first + __holeIndex) = *(__first + (__secondChild - 1));
00289 __holeIndex = __secondChild - 1;
00290 }
00291 std::__push_heap(__first, __holeIndex, __topIndex, __value, __comp);
00292 }
00293
00294 template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
00295 inline void
00296 __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00297 _RandomAccessIterator __result, _Tp __value, _Compare __comp)
00298 {
00299 typedef typename iterator_traits<_RandomAccessIterator>::difference_type
00300 _Distance;
00301 *__result = *__first;
00302 std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first),
00303 __value, __comp);
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 template<typename _RandomAccessIterator, typename _Compare>
00318 inline void
00319 pop_heap(_RandomAccessIterator __first,
00320 _RandomAccessIterator __last, _Compare __comp)
00321 {
00322
00323 __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00324 _RandomAccessIterator>)
00325 __glibcxx_requires_valid_range(__first, __last);
00326 __glibcxx_requires_heap_pred(__first, __last, __comp);
00327
00328 typedef typename iterator_traits<_RandomAccessIterator>::value_type
00329 _ValueType;
00330 std::__pop_heap(__first, __last - 1, __last - 1,
00331 _ValueType(*(__last - 1)), __comp);
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 template<typename _RandomAccessIterator>
00343 void
00344 make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00345 {
00346 typedef typename iterator_traits<_RandomAccessIterator>::value_type
00347 _ValueType;
00348 typedef typename iterator_traits<_RandomAccessIterator>::difference_type
00349 _DistanceType;
00350
00351
00352 __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00353 _RandomAccessIterator>)
00354 __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
00355 __glibcxx_requires_valid_range(__first, __last);
00356
00357 if (__last - __first < 2)
00358 return;
00359
00360 const _DistanceType __len = __last - __first;
00361 _DistanceType __parent = (__len - 2) / 2;
00362 while (true)
00363 {
00364 std::__adjust_heap(__first, __parent, __len,
00365 _ValueType(*(__first + __parent)));
00366 if (__parent == 0)
00367 return;
00368 __parent--;
00369 }
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 template<typename _RandomAccessIterator, typename _Compare>
00383 inline void
00384 make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00385 _Compare __comp)
00386 {
00387 typedef typename iterator_traits<_RandomAccessIterator>::value_type
00388 _ValueType;
00389 typedef typename iterator_traits<_RandomAccessIterator>::difference_type
00390 _DistanceType;
00391
00392
00393 __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00394 _RandomAccessIterator>)
00395 __glibcxx_requires_valid_range(__first, __last);
00396
00397 if (__last - __first < 2)
00398 return;
00399
00400 const _DistanceType __len = __last - __first;
00401 _DistanceType __parent = (__len - 2) / 2;
00402 while (true)
00403 {
00404 std::__adjust_heap(__first, __parent, __len,
00405 _ValueType(*(__first + __parent)), __comp);
00406 if (__parent == 0)
00407 return;
00408 __parent--;
00409 }
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 template<typename _RandomAccessIterator>
00421 void
00422 sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00423 {
00424
00425 __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00426 _RandomAccessIterator>)
00427 __glibcxx_function_requires(_LessThanComparableConcept<
00428 typename iterator_traits<_RandomAccessIterator>::value_type>)
00429 __glibcxx_requires_valid_range(__first, __last);
00430
00431
00432 while (__last - __first > 1)
00433 std::pop_heap(__first, __last--);
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 template<typename _RandomAccessIterator, typename _Compare>
00447 void
00448 sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00449 _Compare __comp)
00450 {
00451
00452 __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00453 _RandomAccessIterator>)
00454 __glibcxx_requires_valid_range(__first, __last);
00455 __glibcxx_requires_heap_pred(__first, __last, __comp);
00456
00457 while (__last - __first > 1)
00458 std::pop_heap(__first, __last--, __comp);
00459 }
00460
00461 }
00462
00463 #endif
00464
00465
00466
00467