1 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! A priority queue implemented with a binary heap
12
13 #![allow(missing_doc)]
14
15 use std::clone::Clone;
16 use std::mem::{move_val_init, init, replace, swap};
17 use std::slice;
18
19 /// A priority queue implemented with a binary heap
20 #[deriving(Clone)]
21 pub struct PriorityQueue<T> {
22 data: Vec<T>,
23 }
24
25 impl<T:Ord> Container for PriorityQueue<T> {
26 /// Returns the length of the queue
27 fn len(&self) -> uint { self.data.len() }
28 }
29
30 impl<T:Ord> Mutable for PriorityQueue<T> {
31 /// Drop all items from the queue
32 fn clear(&mut self) { self.data.truncate(0) }
33 }
34
35 impl<T:Ord> PriorityQueue<T> {
36 /// An iterator visiting all values in underlying vector, in
37 /// arbitrary order.
38 pub fn iter<'a>(&'a self) -> Items<'a, T> {
39 Items { iter: self.data.iter() }
40 }
41
42 /// Returns the greatest item in the queue - fails if empty
43 pub fn top<'a>(&'a self) -> &'a T { self.data.get(0) }
44
45 /// Returns the greatest item in the queue - None if empty
46 pub fn maybe_top<'a>(&'a self) -> Option<&'a T> {
47 if self.is_empty() { None } else { Some(self.top()) }
48 }
49
50 /// Returns the number of elements the queue can hold without reallocating
51 pub fn capacity(&self) -> uint { self.data.capacity() }
52
53 /// Reserve capacity for exactly n elements in the PriorityQueue.
54 /// Do nothing if the capacity is already sufficient.
55 pub fn reserve_exact(&mut self, n: uint) { self.data.reserve_exact(n) }
56
57 /// Reserve capacity for at least n elements in the PriorityQueue.
58 /// Do nothing if the capacity is already sufficient.
59 pub fn reserve(&mut self, n: uint) {
60 self.data.reserve(n)
61 }
62
63 /// Pop the greatest item from the queue - fails if empty
64 pub fn pop(&mut self) -> T {
65 let mut item = self.data.pop().unwrap();
66 if !self.is_empty() {
67 swap(&mut item, self.data.get_mut(0));
68 self.siftdown(0);
69 }
70 item
71 }
72
73 /// Pop the greatest item from the queue - None if empty
74 pub fn maybe_pop(&mut self) -> Option<T> {
75 if self.is_empty() { None } else { Some(self.pop()) }
76 }
77
78 /// Push an item onto the queue
79 pub fn push(&mut self, item: T) {
80 self.data.push(item);
81 let new_len = self.len() - 1;
82 self.siftup(0, new_len);
83 }
84
85 /// Optimized version of a push followed by a pop
86 pub fn push_pop(&mut self, mut item: T) -> T {
87 if !self.is_empty() && *self.top() > item {
88 swap(&mut item, self.data.get_mut(0));
89 self.siftdown(0);
90 }
91 item
92 }
93
94 /// Optimized version of a pop followed by a push - fails if empty
95 pub fn replace(&mut self, mut item: T) -> T {
96 swap(&mut item, self.data.get_mut(0));
97 self.siftdown(0);
98 item
99 }
100
101 /// Consume the PriorityQueue and return the underlying vector
102 pub fn to_vec(self) -> Vec<T> { let PriorityQueue{data: v} = self; v }
103
104 /// Consume the PriorityQueue and return a vector in sorted
105 /// (ascending) order
106 pub fn to_sorted_vec(self) -> Vec<T> {
107 let mut q = self;
108 let mut end = q.len();
109 while end > 1 {
110 end -= 1;
111 q.data.as_mut_slice().swap(0, end);
112 q.siftdown_range(0, end)
113 }
114 q.to_vec()
115 }
116
117 /// Create an empty PriorityQueue
118 pub fn new() -> PriorityQueue<T> { PriorityQueue{data: vec!(),} }
119
120 /// Create an empty PriorityQueue with capacity `capacity`
121 pub fn with_capacity(capacity: uint) -> PriorityQueue<T> {
122 PriorityQueue { data: Vec::with_capacity(capacity) }
123 }
124
125 /// Create a PriorityQueue from a vector (heapify)
126 pub fn from_vec(xs: Vec<T>) -> PriorityQueue<T> {
127 let mut q = PriorityQueue{data: xs,};
128 let mut n = q.len() / 2;
129 while n > 0 {
130 n -= 1;
131 q.siftdown(n)
132 }
133 q
134 }
135
136 // The implementations of siftup and siftdown use unsafe blocks in
137 // order to move an element out of the vector (leaving behind a
138 // zeroed element), shift along the others and move it back into the
139 // vector over the junk element. This reduces the constant factor
140 // compared to using swaps, which involves twice as many moves.
141 fn siftup(&mut self, start: uint, mut pos: uint) {
142 unsafe {
143 let new = replace(self.data.get_mut(pos), init());
144
145 while pos > start {
146 let parent = (pos - 1) >> 1;
147 if new > *self.data.get(parent) {
148 let x = replace(self.data.get_mut(parent), init());
149 move_val_init(self.data.get_mut(pos), x);
150 pos = parent;
151 continue
152 }
153 break
154 }
155 move_val_init(self.data.get_mut(pos), new);
156 }
157 }
158
159 fn siftdown_range(&mut self, mut pos: uint, end: uint) {
160 unsafe {
161 let start = pos;
162 let new = replace(self.data.get_mut(pos), init());
163
164 let mut child = 2 * pos + 1;
165 while child < end {
166 let right = child + 1;
167 if right < end && !(*self.data.get(child) > *self.data.get(right)) {
168 child = right;
169 }
170 let x = replace(self.data.get_mut(child), init());
171 move_val_init(self.data.get_mut(pos), x);
172 pos = child;
173 child = 2 * pos + 1;
174 }
175
176 move_val_init(self.data.get_mut(pos), new);
177 self.siftup(start, pos);
178 }
179 }
180
181 fn siftdown(&mut self, pos: uint) {
182 let len = self.len();
183 self.siftdown_range(pos, len);
184 }
185 }
186
187 /// PriorityQueue iterator
188 pub struct Items <'a, T> {
189 iter: slice::Items<'a, T>,
190 }
191
192 impl<'a, T> Iterator<&'a T> for Items<'a, T> {
193 #[inline]
194 fn next(&mut self) -> Option<(&'a T)> { self.iter.next() }
195
196 #[inline]
197 fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
198 }
199
200 impl<T: Ord> FromIterator<T> for PriorityQueue<T> {
201 fn from_iter<Iter: Iterator<T>>(iter: Iter) -> PriorityQueue<T> {
202 let mut q = PriorityQueue::new();
203 q.extend(iter);
204 q
205 }
206 }
207
208 impl<T: Ord> Extendable<T> for PriorityQueue<T> {
209 fn extend<Iter: Iterator<T>>(&mut self, mut iter: Iter) {
210 let (lower, _) = iter.size_hint();
211
212 let len = self.capacity();
213 self.reserve(len + lower);
214
215 for elem in iter {
216 self.push(elem);
217 }
218 }
219 }
220
221 #[cfg(test)]
222 mod tests {
223 use priority_queue::PriorityQueue;
224
225 #[test]
226 fn test_iterator() {
227 let data = vec!(5, 9, 3);
228 let iterout = [9, 5, 3];
229 let pq = PriorityQueue::from_vec(data);
230 let mut i = 0;
231 for el in pq.iter() {
232 assert_eq!(*el, iterout[i]);
233 i += 1;
234 }
235 }
236
237 #[test]
238 fn test_top_and_pop() {
239 let data = vec!(2u, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1);
240 let mut sorted = data.clone();
241 sorted.sort();
242 let mut heap = PriorityQueue::from_vec(data);
243 while !heap.is_empty() {
244 assert_eq!(heap.top(), sorted.last().unwrap());
245 assert_eq!(heap.pop(), sorted.pop().unwrap());
246 }
247 }
248
249 #[test]
250 fn test_push() {
251 let mut heap = PriorityQueue::from_vec(vec!(2, 4, 9));
252 assert_eq!(heap.len(), 3);
253 assert!(*heap.top() == 9);
254 heap.push(11);
255 assert_eq!(heap.len(), 4);
256 assert!(*heap.top() == 11);
257 heap.push(5);
258 assert_eq!(heap.len(), 5);
259 assert!(*heap.top() == 11);
260 heap.push(27);
261 assert_eq!(heap.len(), 6);
262 assert!(*heap.top() == 27);
263 heap.push(3);
264 assert_eq!(heap.len(), 7);
265 assert!(*heap.top() == 27);
266 heap.push(103);
267 assert_eq!(heap.len(), 8);
268 assert!(*heap.top() == 103);
269 }
270
271 #[test]
272 fn test_push_unique() {
273 let mut heap = PriorityQueue::from_vec(vec!(box 2, box 4, box 9));
274 assert_eq!(heap.len(), 3);
275 assert!(*heap.top() == box 9);
276 heap.push(box 11);
277 assert_eq!(heap.len(), 4);
278 assert!(*heap.top() == box 11);
279 heap.push(box 5);
280 assert_eq!(heap.len(), 5);
281 assert!(*heap.top() == box 11);
282 heap.push(box 27);
283 assert_eq!(heap.len(), 6);
284 assert!(*heap.top() == box 27);
285 heap.push(box 3);
286 assert_eq!(heap.len(), 7);
287 assert!(*heap.top() == box 27);
288 heap.push(box 103);
289 assert_eq!(heap.len(), 8);
290 assert!(*heap.top() == box 103);
291 }
292
293 #[test]
294 fn test_push_pop() {
295 let mut heap = PriorityQueue::from_vec(vec!(5, 5, 2, 1, 3));
296 assert_eq!(heap.len(), 5);
297 assert_eq!(heap.push_pop(6), 6);
298 assert_eq!(heap.len(), 5);
299 assert_eq!(heap.push_pop(0), 5);
300 assert_eq!(heap.len(), 5);
301 assert_eq!(heap.push_pop(4), 5);
302 assert_eq!(heap.len(), 5);
303 assert_eq!(heap.push_pop(1), 4);
304 assert_eq!(heap.len(), 5);
305 }
306
307 #[test]
308 fn test_replace() {
309 let mut heap = PriorityQueue::from_vec(vec!(5, 5, 2, 1, 3));
310 assert_eq!(heap.len(), 5);
311 assert_eq!(heap.replace(6), 5);
312 assert_eq!(heap.len(), 5);
313 assert_eq!(heap.replace(0), 6);
314 assert_eq!(heap.len(), 5);
315 assert_eq!(heap.replace(4), 5);
316 assert_eq!(heap.len(), 5);
317 assert_eq!(heap.replace(1), 4);
318 assert_eq!(heap.len(), 5);
319 }
320
321 fn check_to_vec(mut data: Vec<int>) {
322 let heap = PriorityQueue::from_vec(data.clone());
323 let mut v = heap.clone().to_vec();
324 v.sort();
325 data.sort();
326
327 assert_eq!(v, data);
328 assert_eq!(heap.to_sorted_vec(), data);
329 }
330
331 #[test]
332 fn test_to_vec() {
333 check_to_vec(vec!());
334 check_to_vec(vec!(5));
335 check_to_vec(vec!(3, 2));
336 check_to_vec(vec!(2, 3));
337 check_to_vec(vec!(5, 1, 2));
338 check_to_vec(vec!(1, 100, 2, 3));
339 check_to_vec(vec!(1, 3, 5, 7, 9, 2, 4, 6, 8, 0));
340 check_to_vec(vec!(2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1));
341 check_to_vec(vec!(9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0));
342 check_to_vec(vec!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
343 check_to_vec(vec!(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));
344 check_to_vec(vec!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2));
345 check_to_vec(vec!(5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1));
346 }
347
348 #[test]
349 #[should_fail]
350 fn test_empty_pop() {
351 let mut heap: PriorityQueue<int> = PriorityQueue::new();
352 heap.pop();
353 }
354
355 #[test]
356 fn test_empty_maybe_pop() {
357 let mut heap: PriorityQueue<int> = PriorityQueue::new();
358 assert!(heap.maybe_pop().is_none());
359 }
360
361 #[test]
362 #[should_fail]
363 fn test_empty_top() {
364 let empty: PriorityQueue<int> = PriorityQueue::new();
365 empty.top();
366 }
367
368 #[test]
369 fn test_empty_maybe_top() {
370 let empty: PriorityQueue<int> = PriorityQueue::new();
371 assert!(empty.maybe_top().is_none());
372 }
373
374 #[test]
375 #[should_fail]
376 fn test_empty_replace() {
377 let mut heap: PriorityQueue<int> = PriorityQueue::new();
378 heap.replace(5);
379 }
380
381 #[test]
382 fn test_from_iter() {
383 let xs = vec!(9u, 8, 7, 6, 5, 4, 3, 2, 1);
384
385 let mut q: PriorityQueue<uint> = xs.as_slice().iter().rev().map(|&x| x).collect();
386
387 for &x in xs.iter() {
388 assert_eq!(q.pop(), x);
389 }
390 }
391 }