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