1 // Heap implementation -*- C++ -*- 2 3 // Copyright (C) 2001 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 2, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // You should have received a copy of the GNU General Public License along 17 // with this library; see the file COPYING. If not, write to the Free 18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 19 // USA. 20 21 // As a special exception, you may use this file as part of a free software 22 // library without restriction. Specifically, if other files instantiate 23 // templates or use macros or inline functions from this file, or you compile 24 // this file and link it with other files to produce an executable, this 25 // file does not by itself cause the resulting executable to be covered by 26 // the GNU General Public License. This exception does not however 27 // invalidate any other reasons why the executable file might be covered by 28 // the GNU General Public License. 29 30 /* 31 * 32 * Copyright (c) 1994 33 * Hewlett-Packard Company 34 * 35 * Permission to use, copy, modify, distribute and sell this software 36 * and its documentation for any purpose is hereby granted without fee, 37 * provided that the above copyright notice appear in all copies and 38 * that both that copyright notice and this permission notice appear 39 * in supporting documentation. Hewlett-Packard Company makes no 40 * representations about the suitability of this software for any 41 * purpose. It is provided "as is" without express or implied warranty. 42 * 43 * Copyright (c) 1997 44 * Silicon Graphics Computer Systems, Inc. 45 * 46 * Permission to use, copy, modify, distribute and sell this software 47 * and its documentation for any purpose is hereby granted without fee, 48 * provided that the above copyright notice appear in all copies and 49 * that both that copyright notice and this permission notice appear 50 * in supporting documentation. Silicon Graphics makes no 51 * representations about the suitability of this software for any 52 * purpose. It is provided "as is" without express or implied warranty. 53 */ 54 55 /** @file stl_heap.h 56 * This is an internal header file, included by other library headers. 57 * You should not attempt to use it directly. 58 */ 59 60 #ifndef _CPP_BITS_STL_HEAP_H 61 #define _CPP_BITS_STL_HEAP_H 1 62 63 namespace std 64 { 65 66 // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. 67 68 template<typename _RandomAccessIterator, typename _Distance, typename _Tp> 69 void __push_heap(_RandomAccessIterator __first,_Distance __holeIndex,_Distance __topIndex,_Tp __value)70 __push_heap(_RandomAccessIterator __first, 71 _Distance __holeIndex, _Distance __topIndex, _Tp __value) 72 { 73 _Distance __parent = (__holeIndex - 1) / 2; 74 while (__holeIndex > __topIndex && *(__first + __parent) < __value) { 75 *(__first + __holeIndex) = *(__first + __parent); 76 __holeIndex = __parent; 77 __parent = (__holeIndex - 1) / 2; 78 } 79 *(__first + __holeIndex) = __value; 80 } 81 82 template<typename _RandomAccessIterator> 83 inline void push_heap(_RandomAccessIterator __first,_RandomAccessIterator __last)84 push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 85 { 86 typedef typename iterator_traits<_RandomAccessIterator>::value_type 87 _ValueType; 88 typedef typename iterator_traits<_RandomAccessIterator>::difference_type 89 _DistanceType; 90 91 // concept requirements 92 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< 93 _RandomAccessIterator>) 94 __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) 95 96 __push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), 97 _ValueType(*(__last - 1))); 98 } 99 100 template<typename _RandomAccessIterator, typename _Distance, typename _Tp, 101 typename _Compare> 102 void __push_heap(_RandomAccessIterator __first,_Distance __holeIndex,_Distance __topIndex,_Tp __value,_Compare __comp)103 __push_heap(_RandomAccessIterator __first, _Distance __holeIndex, 104 _Distance __topIndex, _Tp __value, _Compare __comp) 105 { 106 _Distance __parent = (__holeIndex - 1) / 2; 107 while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) { 108 *(__first + __holeIndex) = *(__first + __parent); 109 __holeIndex = __parent; 110 __parent = (__holeIndex - 1) / 2; 111 } 112 *(__first + __holeIndex) = __value; 113 } 114 115 template<typename _RandomAccessIterator, typename _Compare> 116 inline void push_heap(_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)117 push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 118 _Compare __comp) 119 { 120 typedef typename iterator_traits<_RandomAccessIterator>::value_type 121 _ValueType; 122 typedef typename iterator_traits<_RandomAccessIterator>::difference_type 123 _DistanceType; 124 125 // concept requirements 126 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< 127 _RandomAccessIterator>) 128 129 __push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), 130 _ValueType(*(__last - 1)), __comp); 131 } 132 133 template<typename _RandomAccessIterator, typename _Distance, typename _Tp> 134 void __adjust_heap(_RandomAccessIterator __first,_Distance __holeIndex,_Distance __len,_Tp __value)135 __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, 136 _Distance __len, _Tp __value) 137 { 138 _Distance __topIndex = __holeIndex; 139 _Distance __secondChild = 2 * __holeIndex + 2; 140 while (__secondChild < __len) { 141 if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) 142 __secondChild--; 143 *(__first + __holeIndex) = *(__first + __secondChild); 144 __holeIndex = __secondChild; 145 __secondChild = 2 * (__secondChild + 1); 146 } 147 if (__secondChild == __len) { 148 *(__first + __holeIndex) = *(__first + (__secondChild - 1)); 149 __holeIndex = __secondChild - 1; 150 } 151 __push_heap(__first, __holeIndex, __topIndex, __value); 152 } 153 154 template<typename _RandomAccessIterator, typename _Tp> 155 inline void __pop_heap(_RandomAccessIterator __first,_RandomAccessIterator __last,_RandomAccessIterator __result,_Tp __value)156 __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 157 _RandomAccessIterator __result, _Tp __value) 158 { 159 typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance; 160 *__result = *__first; 161 __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value); 162 } 163 164 template<typename _RandomAccessIterator> 165 inline void pop_heap(_RandomAccessIterator __first,_RandomAccessIterator __last)166 pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 167 { 168 typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; 169 170 // concept requirements 171 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< 172 _RandomAccessIterator>) 173 __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) 174 175 __pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1))); 176 } 177 178 template<typename _RandomAccessIterator, typename _Distance, 179 typename _Tp, typename _Compare> 180 void __adjust_heap(_RandomAccessIterator __first,_Distance __holeIndex,_Distance __len,_Tp __value,_Compare __comp)181 __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, 182 _Distance __len, _Tp __value, _Compare __comp) 183 { 184 _Distance __topIndex = __holeIndex; 185 _Distance __secondChild = 2 * __holeIndex + 2; 186 while (__secondChild < __len) { 187 if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1)))) 188 __secondChild--; 189 *(__first + __holeIndex) = *(__first + __secondChild); 190 __holeIndex = __secondChild; 191 __secondChild = 2 * (__secondChild + 1); 192 } 193 if (__secondChild == __len) { 194 *(__first + __holeIndex) = *(__first + (__secondChild - 1)); 195 __holeIndex = __secondChild - 1; 196 } 197 __push_heap(__first, __holeIndex, __topIndex, __value, __comp); 198 } 199 200 template<typename _RandomAccessIterator, typename _Tp, typename _Compare> 201 inline void __pop_heap(_RandomAccessIterator __first,_RandomAccessIterator __last,_RandomAccessIterator __result,_Tp __value,_Compare __comp)202 __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 203 _RandomAccessIterator __result, _Tp __value, _Compare __comp) 204 { 205 typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance; 206 *__result = *__first; 207 __adjust_heap(__first, _Distance(0), _Distance(__last - __first), 208 __value, __comp); 209 } 210 211 template<typename _RandomAccessIterator, typename _Compare> 212 inline void pop_heap(_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)213 pop_heap(_RandomAccessIterator __first, 214 _RandomAccessIterator __last, _Compare __comp) 215 { 216 // concept requirements 217 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< 218 _RandomAccessIterator>) 219 220 typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; 221 __pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1)), __comp); 222 } 223 224 template<typename _RandomAccessIterator> 225 void make_heap(_RandomAccessIterator __first,_RandomAccessIterator __last)226 make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 227 { 228 typedef typename iterator_traits<_RandomAccessIterator>::value_type 229 _ValueType; 230 typedef typename iterator_traits<_RandomAccessIterator>::difference_type 231 _DistanceType; 232 233 // concept requirements 234 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< 235 _RandomAccessIterator>) 236 __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) 237 238 if (__last - __first < 2) return; 239 _DistanceType __len = __last - __first; 240 _DistanceType __parent = (__len - 2)/2; 241 242 while (true) { 243 __adjust_heap(__first, __parent, __len, _ValueType(*(__first + __parent))); 244 if (__parent == 0) return; 245 __parent--; 246 } 247 } 248 249 template<typename _RandomAccessIterator, typename _Compare> 250 inline void make_heap(_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)251 make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 252 _Compare __comp) 253 { 254 typedef typename iterator_traits<_RandomAccessIterator>::value_type 255 _ValueType; 256 typedef typename iterator_traits<_RandomAccessIterator>::difference_type 257 _DistanceType; 258 259 // concept requirements 260 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< 261 _RandomAccessIterator>) 262 263 if (__last - __first < 2) return; 264 _DistanceType __len = __last - __first; 265 _DistanceType __parent = (__len - 2)/2; 266 267 while (true) { 268 __adjust_heap(__first, __parent, __len, 269 _ValueType(*(__first + __parent)), __comp); 270 if (__parent == 0) return; 271 __parent--; 272 } 273 } 274 275 template<typename _RandomAccessIterator> 276 void sort_heap(_RandomAccessIterator __first,_RandomAccessIterator __last)277 sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 278 { 279 // concept requirements 280 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< 281 _RandomAccessIterator>) 282 __glibcpp_function_requires(_LessThanComparableConcept< 283 typename iterator_traits<_RandomAccessIterator>::value_type>) 284 285 while (__last - __first > 1) 286 pop_heap(__first, __last--); 287 } 288 289 template<typename _RandomAccessIterator, typename _Compare> 290 void sort_heap(_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)291 sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 292 _Compare __comp) 293 { 294 // concept requirements 295 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< 296 _RandomAccessIterator>) 297 298 while (__last - __first > 1) 299 pop_heap(__first, __last--, __comp); 300 } 301 302 } // namespace std 303 304 #endif /* _CPP_BITS_STL_HEAP_H */ 305 306 // Local Variables: 307 // mode:C++ 308 // End: 309