1 // Heap implementation -*- C++ -*-
3 // Copyright (C) 2001 Free Software Foundation, Inc.
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)
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.
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,
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.
33 * Hewlett-Packard Company
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.
44 * Silicon Graphics Computer Systems, Inc.
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.
55 /* NOTE: This is an internal header file, included by other STL headers.
56 * You should not attempt to use it directly.
59 #ifndef _CPP_BITS_STL_HEAP_H
60 #define _CPP_BITS_STL_HEAP_H 1
65 // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap.
67 template <class _RandomAccessIterator, class _Distance, class _Tp>
69 __push_heap(_RandomAccessIterator __first,
70 _Distance __holeIndex, _Distance __topIndex, _Tp __value)
72 _Distance __parent = (__holeIndex - 1) / 2;
73 while (__holeIndex > __topIndex && *(__first + __parent) < __value) {
74 *(__first + __holeIndex) = *(__first + __parent);
75 __holeIndex = __parent;
76 __parent = (__holeIndex - 1) / 2;
78 *(__first + __holeIndex) = __value;
81 template <class _RandomAccessIterator, class _Distance, class _Tp>
83 __push_heap_aux(_RandomAccessIterator __first,
84 _RandomAccessIterator __last, _Distance*, _Tp*)
86 __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0),
90 template <class _RandomAccessIterator>
92 push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
94 // concept requirements
95 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
96 _RandomAccessIterator>);
97 __glibcpp_function_requires(_LessThanComparableConcept<
98 typename iterator_traits<_RandomAccessIterator>::value_type>);
100 __push_heap_aux(__first, __last,
101 __distance_type(__first), __value_type(__first));
104 template <class _RandomAccessIterator, class _Distance, class _Tp,
107 __push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
108 _Distance __topIndex, _Tp __value, _Compare __comp)
110 _Distance __parent = (__holeIndex - 1) / 2;
111 while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) {
112 *(__first + __holeIndex) = *(__first + __parent);
113 __holeIndex = __parent;
114 __parent = (__holeIndex - 1) / 2;
116 *(__first + __holeIndex) = __value;
119 template <class _RandomAccessIterator, class _Compare,
120 class _Distance, class _Tp>
122 __push_heap_aux(_RandomAccessIterator __first,
123 _RandomAccessIterator __last, _Compare __comp,
126 __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0),
127 _Tp(*(__last - 1)), __comp);
130 template <class _RandomAccessIterator, class _Compare>
132 push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
135 // concept requirements
136 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
137 _RandomAccessIterator>);
139 __push_heap_aux(__first, __last, __comp,
140 __distance_type(__first), __value_type(__first));
143 template <class _RandomAccessIterator, class _Distance, class _Tp>
145 __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
146 _Distance __len, _Tp __value)
148 _Distance __topIndex = __holeIndex;
149 _Distance __secondChild = 2 * __holeIndex + 2;
150 while (__secondChild < __len) {
151 if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
153 *(__first + __holeIndex) = *(__first + __secondChild);
154 __holeIndex = __secondChild;
155 __secondChild = 2 * (__secondChild + 1);
157 if (__secondChild == __len) {
158 *(__first + __holeIndex) = *(__first + (__secondChild - 1));
159 __holeIndex = __secondChild - 1;
161 __push_heap(__first, __holeIndex, __topIndex, __value);
164 template <class _RandomAccessIterator, class _Tp, class _Distance>
166 __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
167 _RandomAccessIterator __result, _Tp __value, _Distance*)
169 *__result = *__first;
170 __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value);
173 template <class _RandomAccessIterator, class _Tp>
175 __pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last,
178 __pop_heap(__first, __last - 1, __last - 1,
179 _Tp(*(__last - 1)), __distance_type(__first));
182 template <class _RandomAccessIterator>
183 inline void pop_heap(_RandomAccessIterator __first,
184 _RandomAccessIterator __last)
186 // concept requirements
187 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
188 _RandomAccessIterator>);
189 __glibcpp_function_requires(_LessThanComparableConcept<
190 typename iterator_traits<_RandomAccessIterator>::value_type>);
192 __pop_heap_aux(__first, __last, __value_type(__first));
195 template <class _RandomAccessIterator, class _Distance,
196 class _Tp, class _Compare>
198 __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
199 _Distance __len, _Tp __value, _Compare __comp)
201 _Distance __topIndex = __holeIndex;
202 _Distance __secondChild = 2 * __holeIndex + 2;
203 while (__secondChild < __len) {
204 if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1))))
206 *(__first + __holeIndex) = *(__first + __secondChild);
207 __holeIndex = __secondChild;
208 __secondChild = 2 * (__secondChild + 1);
210 if (__secondChild == __len) {
211 *(__first + __holeIndex) = *(__first + (__secondChild - 1));
212 __holeIndex = __secondChild - 1;
214 __push_heap(__first, __holeIndex, __topIndex, __value, __comp);
217 template <class _RandomAccessIterator, class _Tp, class _Compare,
220 __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
221 _RandomAccessIterator __result, _Tp __value, _Compare __comp,
224 *__result = *__first;
225 __adjust_heap(__first, _Distance(0), _Distance(__last - __first),
229 template <class _RandomAccessIterator, class _Tp, class _Compare>
231 __pop_heap_aux(_RandomAccessIterator __first,
232 _RandomAccessIterator __last, _Tp*, _Compare __comp)
234 __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp,
235 __distance_type(__first));
238 template <class _RandomAccessIterator, class _Compare>
240 pop_heap(_RandomAccessIterator __first,
241 _RandomAccessIterator __last, _Compare __comp)
243 // concept requirements
244 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
245 _RandomAccessIterator>);
247 __pop_heap_aux(__first, __last, __value_type(__first), __comp);
250 template <class _RandomAccessIterator, class _Tp, class _Distance>
252 __make_heap(_RandomAccessIterator __first,
253 _RandomAccessIterator __last, _Tp*, _Distance*)
255 if (__last - __first < 2) return;
256 _Distance __len = __last - __first;
257 _Distance __parent = (__len - 2)/2;
260 __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)));
261 if (__parent == 0) return;
266 template <class _RandomAccessIterator>
268 make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
270 // concept requirements
271 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
272 _RandomAccessIterator>);
273 __glibcpp_function_requires(_LessThanComparableConcept<
274 typename iterator_traits<_RandomAccessIterator>::value_type>);
276 __make_heap(__first, __last,
277 __value_type(__first), __distance_type(__first));
280 template <class _RandomAccessIterator, class _Compare,
281 class _Tp, class _Distance>
283 __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
284 _Compare __comp, _Tp*, _Distance*)
286 if (__last - __first < 2) return;
287 _Distance __len = __last - __first;
288 _Distance __parent = (__len - 2)/2;
291 __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)),
293 if (__parent == 0) return;
298 template <class _RandomAccessIterator, class _Compare>
300 make_heap(_RandomAccessIterator __first,
301 _RandomAccessIterator __last, _Compare __comp)
303 // concept requirements
304 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
305 _RandomAccessIterator>);
307 __make_heap(__first, __last, __comp,
308 __value_type(__first), __distance_type(__first));
311 template <class _RandomAccessIterator>
312 void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
314 // concept requirements
315 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
316 _RandomAccessIterator>);
317 __glibcpp_function_requires(_LessThanComparableConcept<
318 typename iterator_traits<_RandomAccessIterator>::value_type>);
320 while (__last - __first > 1)
321 pop_heap(__first, __last--);
324 template <class _RandomAccessIterator, class _Compare>
326 sort_heap(_RandomAccessIterator __first,
327 _RandomAccessIterator __last, _Compare __comp)
329 // concept requirements
330 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
331 _RandomAccessIterator>);
333 while (__last - __first > 1)
334 pop_heap(__first, __last--, __comp);
339 #endif /* _CPP_BITS_STL_HEAP_H */