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