Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: packages/collection/lib/priority_queue.dart

Issue 2989763002: Update charted to 0.4.8 and roll (Closed)
Patch Set: Removed Cutch from list of reviewers Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « packages/collection/lib/iterable_zip.dart ('k') | packages/collection/lib/src/algorithms.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// Import `collection.dart` instead.
6 @Deprecated("Will be removed in collection 2.0.0.")
5 library dart.pkg.collection.priority_queue; 7 library dart.pkg.collection.priority_queue;
6 8
7 import "dart:collection" show SplayTreeSet; 9 export "src/priority_queue.dart";
8
9 /**
10 * A priority queue is a priority based work-list of elements.
11 *
12 * The queue allows adding elements, and removing them again in priority order.
13 */
14 abstract class PriorityQueue<E> {
15 /**
16 * Number of elements in the queue.
17 */
18 int get length;
19
20 /**
21 * Whether the queue is empty.
22 */
23 bool get isEmpty;
24
25 /**
26 * Whether the queue has any elements.
27 */
28 bool get isNotEmpty;
29
30 /**
31 * Checks if [object] is in the queue.
32 *
33 * Returns true if the element is found.
34 */
35 bool contains(E object);
36
37 /**
38 * Adds element to the queue.
39 *
40 * The element will become the next to be removed by [removeFirst]
41 * when all elements with higher priority have been removed.
42 */
43 void add(E element);
44
45 /**
46 * Adds all [elements] to the queue.
47 */
48 void addAll(Iterable<E> elements);
49
50 /**
51 * Returns the next element that will be returned by [removeFirst].
52 *
53 * The element is not removed from the queue.
54 *
55 * The queue must not be empty when this method is called.
56 */
57 E get first;
58
59 /**
60 * Removes and returns the element with the highest priority.
61 *
62 * Repeatedly calling this method, without adding element in between,
63 * is guaranteed to return elements in non-decreasing order as, specified by
64 * [comparison].
65 *
66 * The queue must not be empty when this method is called.
67 */
68 E removeFirst();
69
70 /**
71 * Removes an element that compares equal to [element] in the queue.
72 *
73 * Returns true if an element is found and removed,
74 * and false if no equal element is found.
75 */
76 bool remove(E element);
77
78 /**
79 * Removes all the elements from this queue and returns them.
80 *
81 * The returned iterable has no specified order.
82 */
83 Iterable<E> removeAll();
84
85 /**
86 * Removes all the elements from this queue.
87 */
88 void clear();
89
90 /**
91 * Returns a list of the elements of this queue in priority order.
92 *
93 * The queue is not modified.
94 *
95 * The order is the order that the elements would be in if they were
96 * removed from this queue using [removeFirst].
97 */
98 List<E> toList();
99
100 /**
101 * Return a comparator based set using the comparator of this queue.
102 *
103 * The queue is not modified.
104 *
105 * The returned [Set] is currently a [SplayTreeSet],
106 * but this may change as other ordered sets are implemented.
107 *
108 * The set contains all the elements of this queue.
109 * If an element occurs more than once in the queue,
110 * the set will contain it only once.
111 */
112 Set<E> toSet();
113 }
114
115 /**
116 * Heap based priority queue.
117 *
118 * The elements are kept in a heap structure,
119 * where the element with the highest priority is immediately accessible,
120 * and modifying a single element takes
121 * logarithmic time in the number of elements on average.
122 *
123 * * The [add] and [removeFirst] operations take amortized logarithmic time,
124 * O(log(n)), but may occasionally take linear time when growing the capacity
125 * of the heap.
126 * * The [addAll] operation works as doing repeated [add] operations.
127 * * The [first] getter takes constant time, O(1).
128 * * The [clear] and [removeAll] methods also take constant time, O(1).
129 * * The [contains] and [remove] operations may need to search the entire
130 * queue for the elements, taking O(n) time.
131 * * The [toList] operation effectively sorts the elements, taking O(n*log(n))
132 * time.
133 * * The [toSet] operation effectively adds each element to the new set, taking
134 * an expected O(n*log(n)) time.
135 */
136 class HeapPriorityQueue<E> implements PriorityQueue<E> {
137 /**
138 * Initial capacity of a queue when created, or when added to after a [clear].
139 *
140 * Number can be any positive value. Picking a size that gives a whole
141 * number of "tree levels" in the heap is only done for aesthetic reasons.
142 */
143 static const int _INITIAL_CAPACITY = 7;
144
145 /**
146 * The comparison being used to compare the priority of elements.
147 */
148 final Comparator comparison;
149
150 /**
151 * List implementation of a heap.
152 */
153 List<E> _queue = new List<E>(_INITIAL_CAPACITY);
154
155 /**
156 * Number of elements in queue.
157 *
158 * The heap is implemented in the first [_length] entries of [_queue].
159 */
160 int _length = 0;
161
162 /**
163 * Create a new priority queue.
164 *
165 * The [comparison] is a [Comparator] used to compare the priority of
166 * elements. An element that compares as less than another element has
167 * a higher priority.
168 *
169 * If [comparison] is omitted, it defaults to [Comparable.compare].
170 */
171 HeapPriorityQueue([int comparison(E e1, E e2)])
172 : comparison = (comparison != null) ? comparison : Comparable.compare;
173
174 void add(E element) {
175 _add(element);
176 }
177
178 void addAll(Iterable<E> elements) {
179 for (E element in elements) {
180 _add(element);
181 }
182 }
183
184 void clear() {
185 _queue = const [];
186 _length = 0;
187 }
188
189 bool contains(E object) {
190 return _locate(object) >= 0;
191 }
192
193 E get first {
194 if (_length == 0) throw new StateError("No such element");
195 return _queue[0];
196 }
197
198 bool get isEmpty => _length == 0;
199
200 bool get isNotEmpty => _length != 0;
201
202 int get length => _length;
203
204 bool remove(E element) {
205 int index = _locate(element);
206 if (index < 0) return false;
207 E last = _removeLast();
208 if (index < _length) {
209 int comp = comparison(last, element);
210 if (comp <= 0) {
211 _bubbleUp(last, index);
212 } else {
213 _bubbleDown(last, index);
214 }
215 }
216 return true;
217 }
218
219 Iterable<E> removeAll() {
220 List<E> result = _queue;
221 int length = _length;
222 _queue = const [];
223 _length = 0;
224 return result.take(length);
225 }
226
227 E removeFirst() {
228 if (_length == 0) throw new StateError("No such element");
229 E result = _queue[0];
230 E last = _removeLast();
231 if (_length > 0) {
232 _bubbleDown(last, 0);
233 }
234 return result;
235 }
236
237 List<E> toList() {
238 List<E> list = new List<E>()..length = _length;
239 list.setRange(0, _length, _queue);
240 list.sort(comparison);
241 return list;
242 }
243
244 Set<E> toSet() {
245 Set<E> set = new SplayTreeSet<E>(comparison);
246 for (int i = 0; i < _length; i++) {
247 set.add(_queue[i]);
248 }
249 return set;
250 }
251
252 /**
253 * Returns some representation of the queue.
254 *
255 * The format isn't significant, and may change in the future.
256 */
257 String toString() {
258 return _queue.take(_length).toString();
259 }
260
261 /**
262 * Add element to the queue.
263 *
264 * Grows the capacity if the backing list is full.
265 */
266 void _add(E element) {
267 if (_length == _queue.length) _grow();
268 _bubbleUp(element, _length++);
269 }
270
271 /**
272 * Find the index of an object in the heap.
273 *
274 * Returns -1 if the object is not found.
275 */
276 int _locate(E object) {
277 if (_length == 0) return -1;
278 // Count positions from one instead of zero. This gives the numbers
279 // some nice properties. For example, all right children are odd,
280 // their left sibling is even, and the parent is found by shifting
281 // right by one.
282 // Valid range for position is [1.._length], inclusive.
283 int position = 1;
284 // Pre-order depth first search, omit child nodes if the current
285 // node has lower priority than [object], because all nodes lower
286 // in the heap will also have lower priority.
287 do {
288 int index = position - 1;
289 E element = _queue[index];
290 int comp = comparison(element, object);
291 if (comp == 0) return index;
292 if (comp < 0) {
293 // Element may be in subtree.
294 // Continue with the left child, if it is there.
295 int leftChildPosition = position * 2;
296 if (leftChildPosition <= _length) {
297 position = leftChildPosition;
298 continue;
299 }
300 }
301 // Find the next right sibling or right ancestor sibling.
302 do {
303 while (position.isOdd) {
304 // While position is a right child, go to the parent.
305 position >>= 1;
306 }
307 // Then go to the right sibling of the left-child.
308 position += 1;
309 } while (position > _length); // Happens if last element is a left child.
310 } while (position != 1); // At root again. Happens for right-most element.
311 return -1;
312 }
313
314 E _removeLast() {
315 int newLength = _length - 1;
316 E last = _queue[newLength];
317 _queue[newLength] = null;
318 _length = newLength;
319 return last;
320 }
321
322 /**
323 * Place [element] in heap at [index] or above.
324 *
325 * Put element into the empty cell at `index`.
326 * While the `element` has higher priority than the
327 * parent, swap it with the parent.
328 */
329 void _bubbleUp(E element, int index) {
330 while (index > 0) {
331 int parentIndex = (index - 1) ~/ 2;
332 E parent = _queue[parentIndex];
333 if (comparison(element, parent) > 0) break;
334 _queue[index] = parent;
335 index = parentIndex;
336 }
337 _queue[index] = element;
338 }
339
340 /**
341 * Place [element] in heap at [index] or above.
342 *
343 * Put element into the empty cell at `index`.
344 * While the `element` has lower priority than either child,
345 * swap it with the highest priority child.
346 */
347 void _bubbleDown(E element, int index) {
348 int rightChildIndex = index * 2 + 2;
349 while (rightChildIndex < _length) {
350 int leftChildIndex = rightChildIndex - 1;
351 E leftChild = _queue[leftChildIndex];
352 E rightChild = _queue[rightChildIndex];
353 int comp = comparison(leftChild, rightChild);
354 int minChildIndex;
355 E minChild;
356 if (comp < 0) {
357 minChild = leftChild;
358 minChildIndex = leftChildIndex;
359 } else {
360 minChild = rightChild;
361 minChildIndex = rightChildIndex;
362 }
363 comp = comparison(element, minChild);
364 if (comp <= 0) {
365 _queue[index] = element;
366 return;
367 }
368 _queue[index] = minChild;
369 index = minChildIndex;
370 rightChildIndex = index * 2 + 2;
371 }
372 int leftChildIndex = rightChildIndex - 1;
373 if (leftChildIndex < _length) {
374 E child = _queue[leftChildIndex];
375 int comp = comparison(element, child);
376 if (comp > 0) {
377 _queue[index] = child;
378 index = leftChildIndex;
379 }
380 }
381 _queue[index] = element;
382 }
383
384 /**
385 * Grows the capacity of the list holding the heap.
386 *
387 * Called when the list is full.
388 */
389 void _grow() {
390 int newCapacity = _queue.length * 2 + 1;
391 if (newCapacity < _INITIAL_CAPACITY) newCapacity = _INITIAL_CAPACITY;
392 List<E> newQueue = new List<E>(newCapacity);
393 newQueue.setRange(0, _length, _queue);
394 _queue = newQueue;
395 }
396 }
OLDNEW
« no previous file with comments | « packages/collection/lib/iterable_zip.dart ('k') | packages/collection/lib/src/algorithms.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698