]> git.lizzy.rs Git - rust.git/blob - src/libcollections/binary_heap.rs
auto merge of #19628 : jbranchaud/rust/add-string-as-string-doctest, r=steveklabnik
[rust.git] / src / libcollections / binary_heap.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 //! Insertion and popping the largest element have `O(log n)` time complexity. Checking the largest
14 //! element is `O(1)`. Converting a vector to a priority queue can be done in-place, and has `O(n)`
15 //! complexity. A priority queue can also be converted to a sorted vector in-place, allowing it to
16 //! be used for an `O(n log n)` in-place heapsort.
17 //!
18 //! # Example
19 //!
20 //! This is a larger example which implements [Dijkstra's algorithm][dijkstra]
21 //! to solve the [shortest path problem][sssp] on a [directed graph][dir_graph].
22 //! It showcases how to use the `BinaryHeap` with custom types.
23 //!
24 //! [dijkstra]: http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
25 //! [sssp]: http://en.wikipedia.org/wiki/Shortest_path_problem
26 //! [dir_graph]: http://en.wikipedia.org/wiki/Directed_graph
27 //!
28 //! ```
29 //! use std::collections::BinaryHeap;
30 //! use std::uint;
31 //!
32 //! #[deriving(Eq, PartialEq)]
33 //! struct State {
34 //!     cost: uint,
35 //!     position: uint
36 //! }
37 //!
38 //! impl Copy for State {}
39 //!
40 //! // The priority queue depends on `Ord`.
41 //! // Explicitly implement the trait so the queue becomes a min-heap
42 //! // instead of a max-heap.
43 //! impl Ord for State {
44 //!     fn cmp(&self, other: &State) -> Ordering {
45 //!         // Notice that the we flip the ordering here
46 //!         other.cost.cmp(&self.cost)
47 //!     }
48 //! }
49 //!
50 //! // `PartialOrd` needs to be implemented as well.
51 //! impl PartialOrd for State {
52 //!     fn partial_cmp(&self, other: &State) -> Option<Ordering> {
53 //!         Some(self.cmp(other))
54 //!     }
55 //! }
56 //!
57 //! // Each node is represented as an `uint`, for a shorter implementation.
58 //! struct Edge {
59 //!     node: uint,
60 //!     cost: uint
61 //! }
62 //!
63 //! // Dijkstra's shortest path algorithm.
64 //!
65 //! // Start at `start` and use `dist` to track the current shortest distance
66 //! // to each node. This implementation isn't memory efficient as it may leave duplicate
67 //! // nodes in the queue. It also uses `uint::MAX` as a sentinel value,
68 //! // for a simpler implementation.
69 //! fn shortest_path(adj_list: &Vec<Vec<Edge>>, start: uint, goal: uint) -> uint {
70 //!     // dist[node] = current shortest distance from `start` to `node`
71 //!     let mut dist = Vec::from_elem(adj_list.len(), uint::MAX);
72 //!
73 //!     let mut heap = BinaryHeap::new();
74 //!
75 //!     // We're at `start`, with a zero cost
76 //!     dist[start] = 0u;
77 //!     heap.push(State { cost: 0u, position: start });
78 //!
79 //!     // Examine the frontier with lower cost nodes first (min-heap)
80 //!     loop {
81 //!         let State { cost, position } = match heap.pop() {
82 //!             None => break, // empty
83 //!             Some(s) => s
84 //!         };
85 //!
86 //!         // Alternatively we could have continued to find all shortest paths
87 //!         if position == goal { return cost }
88 //!
89 //!         // Important as we may have already found a better way
90 //!         if cost > dist[position] { continue }
91 //!
92 //!         // For each node we can reach, see if we can find a way with
93 //!         // a lower cost going through this node
94 //!         for edge in adj_list[position].iter() {
95 //!             let next = State { cost: cost + edge.cost, position: edge.node };
96 //!
97 //!             // If so, add it to the frontier and continue
98 //!             if next.cost < dist[next.position] {
99 //!                 heap.push(next);
100 //!                 // Relaxation, we have now found a better way
101 //!                 dist[next.position] = next.cost;
102 //!             }
103 //!         }
104 //!     }
105 //!
106 //!     // Goal not reachable
107 //!     uint::MAX
108 //! }
109 //!
110 //! fn main() {
111 //!     // This is the directed graph we're going to use.
112 //!     // The node numbers correspond to the different states,
113 //!     // and the edge weights symbolises the cost of moving
114 //!     // from one node to another.
115 //!     // Note that the edges are one-way.
116 //!     //
117 //!     //                  7
118 //!     //          +-----------------+
119 //!     //          |                 |
120 //!     //          v   1        2    |
121 //!     //          0 -----> 1 -----> 3 ---> 4
122 //!     //          |        ^        ^      ^
123 //!     //          |        | 1      |      |
124 //!     //          |        |        | 3    | 1
125 //!     //          +------> 2 -------+      |
126 //!     //           10      |               |
127 //!     //                   +---------------+
128 //!     //
129 //!     // The graph is represented as an adjacency list where each index,
130 //!     // corresponding to a node value, has a list of outgoing edges.
131 //!     // Chosen for it's efficiency.
132 //!     let graph = vec![
133 //!         // Node 0
134 //!         vec![Edge { node: 2, cost: 10 },
135 //!              Edge { node: 1, cost: 1 }],
136 //!         // Node 1
137 //!         vec![Edge { node: 3, cost: 2 }],
138 //!         // Node 2
139 //!         vec![Edge { node: 1, cost: 1 },
140 //!              Edge { node: 3, cost: 3 },
141 //!              Edge { node: 4, cost: 1 }],
142 //!         // Node 3
143 //!         vec![Edge { node: 0, cost: 7 },
144 //!              Edge { node: 4, cost: 2 }],
145 //!         // Node 4
146 //!         vec![]];
147 //!
148 //!     assert_eq!(shortest_path(&graph, 0, 1), 1);
149 //!     assert_eq!(shortest_path(&graph, 0, 3), 3);
150 //!     assert_eq!(shortest_path(&graph, 3, 0), 7);
151 //!     assert_eq!(shortest_path(&graph, 0, 4), 5);
152 //!     assert_eq!(shortest_path(&graph, 4, 0), uint::MAX);
153 //! }
154 //! ```
155
156 #![allow(missing_docs)]
157
158 use core::prelude::*;
159
160 use core::default::Default;
161 use core::mem::{zeroed, replace, swap};
162 use core::ptr;
163
164 use slice;
165 use vec::{mod, Vec};
166
167 /// A priority queue implemented with a binary heap.
168 ///
169 /// This will be a max-heap.
170 #[deriving(Clone)]
171 pub struct BinaryHeap<T> {
172     data: Vec<T>,
173 }
174
175 impl<T: Ord> Default for BinaryHeap<T> {
176     #[inline]
177     fn default() -> BinaryHeap<T> { BinaryHeap::new() }
178 }
179
180 impl<T: Ord> BinaryHeap<T> {
181     /// Creates an empty `BinaryHeap` as a max-heap.
182     ///
183     /// # Example
184     ///
185     /// ```
186     /// use std::collections::BinaryHeap;
187     /// let heap: BinaryHeap<uint> = BinaryHeap::new();
188     /// ```
189     #[unstable = "matches collection reform specification, waiting for dust to settle"]
190     pub fn new() -> BinaryHeap<T> { BinaryHeap{data: vec!(),} }
191
192     /// Creates an empty `BinaryHeap` with a specific capacity.
193     /// This preallocates enough memory for `capacity` elements,
194     /// so that the `BinaryHeap` does not have to be reallocated
195     /// until it contains at least that many values.
196     ///
197     /// # Example
198     ///
199     /// ```
200     /// use std::collections::BinaryHeap;
201     /// let heap: BinaryHeap<uint> = BinaryHeap::with_capacity(10u);
202     /// ```
203     #[unstable = "matches collection reform specification, waiting for dust to settle"]
204     pub fn with_capacity(capacity: uint) -> BinaryHeap<T> {
205         BinaryHeap { data: Vec::with_capacity(capacity) }
206     }
207
208     /// Creates a `BinaryHeap` from a vector. This is sometimes called
209     /// `heapifying` the vector.
210     ///
211     /// # Example
212     ///
213     /// ```
214     /// use std::collections::BinaryHeap;
215     /// let heap = BinaryHeap::from_vec(vec![9i, 1, 2, 7, 3, 2]);
216     /// ```
217     pub fn from_vec(xs: Vec<T>) -> BinaryHeap<T> {
218         let mut q = BinaryHeap{data: xs,};
219         let mut n = q.len() / 2;
220         while n > 0 {
221             n -= 1;
222             q.siftdown(n)
223         }
224         q
225     }
226
227     /// An iterator visiting all values in underlying vector, in
228     /// arbitrary order.
229     ///
230     /// # Example
231     ///
232     /// ```
233     /// use std::collections::BinaryHeap;
234     /// let heap = BinaryHeap::from_vec(vec![1i, 2, 3, 4]);
235     ///
236     /// // Print 1, 2, 3, 4 in arbitrary order
237     /// for x in heap.iter() {
238     ///     println!("{}", x);
239     /// }
240     /// ```
241     #[unstable = "matches collection reform specification, waiting for dust to settle"]
242     pub fn iter<'a>(&'a self) -> Items<'a, T> {
243         Items { iter: self.data.iter() }
244     }
245
246     /// Creates a consuming iterator, that is, one that moves each value out of
247     /// the binary heap in arbitrary order.  The binary heap cannot be used
248     /// after calling this.
249     ///
250     /// # Example
251     ///
252     /// ```
253     /// use std::collections::BinaryHeap;
254     /// let pq = BinaryHeap::from_vec(vec![1i, 2, 3, 4]);
255     ///
256     /// // Print 1, 2, 3, 4 in arbitrary order
257     /// for x in pq.into_iter() {
258     ///     // x has type int, not &int
259     ///     println!("{}", x);
260     /// }
261     /// ```
262     #[unstable = "matches collection reform specification, waiting for dust to settle"]
263     pub fn into_iter(self) -> MoveItems<T> {
264         MoveItems { iter: self.data.into_iter() }
265     }
266
267     /// Returns the greatest item in a queue, or `None` if it is empty.
268     ///
269     /// # Example
270     ///
271     /// ```
272     /// use std::collections::BinaryHeap;
273     ///
274     /// let mut heap = BinaryHeap::new();
275     /// assert_eq!(heap.top(), None);
276     ///
277     /// heap.push(1i);
278     /// heap.push(5i);
279     /// heap.push(2i);
280     /// assert_eq!(heap.top(), Some(&5i));
281     ///
282     /// ```
283     pub fn top<'a>(&'a self) -> Option<&'a T> {
284         if self.is_empty() { None } else { Some(&self.data[0]) }
285     }
286
287     /// Returns the number of elements the queue can hold without reallocating.
288     ///
289     /// # Example
290     ///
291     /// ```
292     /// use std::collections::BinaryHeap;
293     ///
294     /// let heap: BinaryHeap<uint> = BinaryHeap::with_capacity(100u);
295     /// assert!(heap.capacity() >= 100u);
296     /// ```
297     #[unstable = "matches collection reform specification, waiting for dust to settle"]
298     pub fn capacity(&self) -> uint { self.data.capacity() }
299
300     /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the
301     /// given `BinaryHeap`. Does nothing if the capacity is already sufficient.
302     ///
303     /// Note that the allocator may give the collection more space than it requests. Therefore
304     /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
305     /// insertions are expected.
306     ///
307     /// # Panics
308     ///
309     /// Panics if the new capacity overflows `uint`.
310     ///
311     /// # Example
312     ///
313     /// ```
314     /// use std::collections::BinaryHeap;
315     ///
316     /// let mut heap: BinaryHeap<uint> = BinaryHeap::new();
317     /// heap.reserve_exact(100u);
318     /// assert!(heap.capacity() >= 100u);
319     /// ```
320     #[unstable = "matches collection reform specification, waiting for dust to settle"]
321     pub fn reserve_exact(&mut self, additional: uint) { self.data.reserve_exact(additional) }
322
323     /// Reserves capacity for at least `additional` more elements to be inserted in the
324     /// `BinaryHeap`. The collection may reserve more space to avoid frequent reallocations.
325     ///
326     /// # Panics
327     ///
328     /// Panics if the new capacity overflows `uint`.
329     ///
330     /// # Example
331     ///
332     /// ```
333     /// use std::collections::BinaryHeap;
334     ///
335     /// let mut heap: BinaryHeap<uint> = BinaryHeap::new();
336     /// heap.reserve(100u);
337     /// assert!(heap.capacity() >= 100u);
338     /// ```
339     #[unstable = "matches collection reform specification, waiting for dust to settle"]
340     pub fn reserve(&mut self, additional: uint) {
341         self.data.reserve(additional)
342     }
343
344     /// Discards as much additional capacity as possible.
345     #[unstable = "matches collection reform specification, waiting for dust to settle"]
346     pub fn shrink_to_fit(&mut self) {
347         self.data.shrink_to_fit()
348     }
349
350     /// Removes the greatest item from a queue and returns it, or `None` if it
351     /// is empty.
352     ///
353     /// # Example
354     ///
355     /// ```
356     /// use std::collections::BinaryHeap;
357     ///
358     /// let mut heap = BinaryHeap::from_vec(vec![1i, 3]);
359     ///
360     /// assert_eq!(heap.pop(), Some(3i));
361     /// assert_eq!(heap.pop(), Some(1i));
362     /// assert_eq!(heap.pop(), None);
363     /// ```
364     #[unstable = "matches collection reform specification, waiting for dust to settle"]
365     pub fn pop(&mut self) -> Option<T> {
366         match self.data.pop() {
367             None           => { None }
368             Some(mut item) => {
369                 if !self.is_empty() {
370                     swap(&mut item, &mut self.data[0]);
371                     self.siftdown(0);
372                 }
373                 Some(item)
374             }
375         }
376     }
377
378     /// Pushes an item onto the queue.
379     ///
380     /// # Example
381     ///
382     /// ```
383     /// use std::collections::BinaryHeap;
384     ///
385     /// let mut heap = BinaryHeap::new();
386     /// heap.push(3i);
387     /// heap.push(5i);
388     /// heap.push(1i);
389     ///
390     /// assert_eq!(heap.len(), 3);
391     /// assert_eq!(heap.top(), Some(&5i));
392     /// ```
393     #[unstable = "matches collection reform specification, waiting for dust to settle"]
394     pub fn push(&mut self, item: T) {
395         self.data.push(item);
396         let new_len = self.len() - 1;
397         self.siftup(0, new_len);
398     }
399
400     /// Pushes an item onto a queue then pops the greatest item off the queue in
401     /// an optimized fashion.
402     ///
403     /// # Example
404     ///
405     /// ```
406     /// use std::collections::BinaryHeap;
407     ///
408     /// let mut heap = BinaryHeap::new();
409     /// heap.push(1i);
410     /// heap.push(5i);
411     ///
412     /// assert_eq!(heap.push_pop(3i), 5);
413     /// assert_eq!(heap.push_pop(9i), 9);
414     /// assert_eq!(heap.len(), 2);
415     /// assert_eq!(heap.top(), Some(&3i));
416     /// ```
417     pub fn push_pop(&mut self, mut item: T) -> T {
418         if !self.is_empty() && *self.top().unwrap() > item {
419             swap(&mut item, &mut self.data[0]);
420             self.siftdown(0);
421         }
422         item
423     }
424
425     /// Pops the greatest item off a queue then pushes an item onto the queue in
426     /// an optimized fashion. The push is done regardless of whether the queue
427     /// was empty.
428     ///
429     /// # Example
430     ///
431     /// ```
432     /// use std::collections::BinaryHeap;
433     ///
434     /// let mut heap = BinaryHeap::new();
435     ///
436     /// assert_eq!(heap.replace(1i), None);
437     /// assert_eq!(heap.replace(3i), Some(1i));
438     /// assert_eq!(heap.len(), 1);
439     /// assert_eq!(heap.top(), Some(&3i));
440     /// ```
441     pub fn replace(&mut self, mut item: T) -> Option<T> {
442         if !self.is_empty() {
443             swap(&mut item, &mut self.data[0]);
444             self.siftdown(0);
445             Some(item)
446         } else {
447             self.push(item);
448             None
449         }
450     }
451
452     /// Consumes the `BinaryHeap` and returns the underlying vector
453     /// in arbitrary order.
454     ///
455     /// # Example
456     ///
457     /// ```
458     /// use std::collections::BinaryHeap;
459     ///
460     /// let heap = BinaryHeap::from_vec(vec![1i, 2, 3, 4, 5, 6, 7]);
461     /// let vec = heap.into_vec();
462     ///
463     /// // Will print in some order
464     /// for x in vec.iter() {
465     ///     println!("{}", x);
466     /// }
467     /// ```
468     pub fn into_vec(self) -> Vec<T> { let BinaryHeap{data: v} = self; v }
469
470     /// Consumes the `BinaryHeap` and returns a vector in sorted
471     /// (ascending) order.
472     ///
473     /// # Example
474     ///
475     /// ```
476     /// use std::collections::BinaryHeap;
477     ///
478     /// let mut heap = BinaryHeap::from_vec(vec![1i, 2, 4, 5, 7]);
479     /// heap.push(6);
480     /// heap.push(3);
481     ///
482     /// let vec = heap.into_sorted_vec();
483     /// assert_eq!(vec, vec![1i, 2, 3, 4, 5, 6, 7]);
484     /// ```
485     pub fn into_sorted_vec(self) -> Vec<T> {
486         let mut q = self;
487         let mut end = q.len();
488         while end > 1 {
489             end -= 1;
490             q.data.swap(0, end);
491             q.siftdown_range(0, end)
492         }
493         q.into_vec()
494     }
495
496     // The implementations of siftup and siftdown use unsafe blocks in
497     // order to move an element out of the vector (leaving behind a
498     // zeroed element), shift along the others and move it back into the
499     // vector over the junk element.  This reduces the constant factor
500     // compared to using swaps, which involves twice as many moves.
501     fn siftup(&mut self, start: uint, mut pos: uint) {
502         unsafe {
503             let new = replace(&mut self.data[pos], zeroed());
504
505             while pos > start {
506                 let parent = (pos - 1) >> 1;
507                 if new > self.data[parent] {
508                     let x = replace(&mut self.data[parent], zeroed());
509                     ptr::write(&mut self.data[pos], x);
510                     pos = parent;
511                     continue
512                 }
513                 break
514             }
515             ptr::write(&mut self.data[pos], new);
516         }
517     }
518
519     fn siftdown_range(&mut self, mut pos: uint, end: uint) {
520         unsafe {
521             let start = pos;
522             let new = replace(&mut self.data[pos], zeroed());
523
524             let mut child = 2 * pos + 1;
525             while child < end {
526                 let right = child + 1;
527                 if right < end && !(self.data[child] > self.data[right]) {
528                     child = right;
529                 }
530                 let x = replace(&mut self.data[child], zeroed());
531                 ptr::write(&mut self.data[pos], x);
532                 pos = child;
533                 child = 2 * pos + 1;
534             }
535
536             ptr::write(&mut self.data[pos], new);
537             self.siftup(start, pos);
538         }
539     }
540
541     fn siftdown(&mut self, pos: uint) {
542         let len = self.len();
543         self.siftdown_range(pos, len);
544     }
545
546     /// Returns the length of the queue.
547     #[unstable = "matches collection reform specification, waiting for dust to settle"]
548     pub fn len(&self) -> uint { self.data.len() }
549
550     /// Returns true if the queue contains no elements
551     #[unstable = "matches collection reform specification, waiting for dust to settle"]
552     pub fn is_empty(&self) -> bool { self.len() == 0 }
553
554     /// Drops all items from the queue.
555     #[unstable = "matches collection reform specification, waiting for dust to settle"]
556     pub fn clear(&mut self) { self.data.truncate(0) }
557 }
558
559 /// `BinaryHeap` iterator.
560 pub struct Items <'a, T:'a> {
561     iter: slice::Items<'a, T>,
562 }
563
564 impl<'a, T> Iterator<&'a T> for Items<'a, T> {
565     #[inline]
566     fn next(&mut self) -> Option<(&'a T)> { self.iter.next() }
567
568     #[inline]
569     fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
570 }
571
572 impl<'a, T> DoubleEndedIterator<&'a T> for Items<'a, T> {
573     #[inline]
574     fn next_back(&mut self) -> Option<(&'a T)> { self.iter.next_back() }
575 }
576
577 impl<'a, T> ExactSizeIterator<&'a T> for Items<'a, T> {}
578
579 /// An iterator that moves out of a `BinaryHeap`.
580 pub struct MoveItems<T> {
581     iter: vec::MoveItems<T>,
582 }
583
584 impl<T> Iterator<T> for MoveItems<T> {
585     #[inline]
586     fn next(&mut self) -> Option<T> { self.iter.next() }
587
588     #[inline]
589     fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
590 }
591
592 impl<T> DoubleEndedIterator<T> for MoveItems<T> {
593     #[inline]
594     fn next_back(&mut self) -> Option<T> { self.iter.next_back() }
595 }
596
597 impl<T> ExactSizeIterator<T> for MoveItems<T> {}
598
599 impl<T: Ord> FromIterator<T> for BinaryHeap<T> {
600     fn from_iter<Iter: Iterator<T>>(iter: Iter) -> BinaryHeap<T> {
601         let vec: Vec<T> = iter.collect();
602         BinaryHeap::from_vec(vec)
603     }
604 }
605
606 impl<T: Ord> Extend<T> for BinaryHeap<T> {
607     fn extend<Iter: Iterator<T>>(&mut self, mut iter: Iter) {
608         let (lower, _) = iter.size_hint();
609
610         self.reserve(lower);
611
612         for elem in iter {
613             self.push(elem);
614         }
615     }
616 }
617
618 #[cfg(test)]
619 mod tests {
620     use std::prelude::*;
621
622     use super::BinaryHeap;
623     use vec::Vec;
624
625     #[test]
626     fn test_iterator() {
627         let data = vec!(5i, 9, 3);
628         let iterout = [9i, 5, 3];
629         let heap = BinaryHeap::from_vec(data);
630         let mut i = 0;
631         for el in heap.iter() {
632             assert_eq!(*el, iterout[i]);
633             i += 1;
634         }
635     }
636
637     #[test]
638     fn test_iterator_reverse() {
639         let data = vec!(5i, 9, 3);
640         let iterout = vec!(3i, 5, 9);
641         let pq = BinaryHeap::from_vec(data);
642
643         let v: Vec<int> = pq.iter().rev().map(|&x| x).collect();
644         assert_eq!(v, iterout);
645     }
646
647     #[test]
648     fn test_move_iter() {
649         let data = vec!(5i, 9, 3);
650         let iterout = vec!(9i, 5, 3);
651         let pq = BinaryHeap::from_vec(data);
652
653         let v: Vec<int> = pq.into_iter().collect();
654         assert_eq!(v, iterout);
655     }
656
657     #[test]
658     fn test_move_iter_size_hint() {
659         let data = vec!(5i, 9);
660         let pq = BinaryHeap::from_vec(data);
661
662         let mut it = pq.into_iter();
663
664         assert_eq!(it.size_hint(), (2, Some(2)));
665         assert_eq!(it.next(), Some(9i));
666
667         assert_eq!(it.size_hint(), (1, Some(1)));
668         assert_eq!(it.next(), Some(5i));
669
670         assert_eq!(it.size_hint(), (0, Some(0)));
671         assert_eq!(it.next(), None);
672     }
673
674     #[test]
675     fn test_move_iter_reverse() {
676         let data = vec!(5i, 9, 3);
677         let iterout = vec!(3i, 5, 9);
678         let pq = BinaryHeap::from_vec(data);
679
680         let v: Vec<int> = pq.into_iter().rev().collect();
681         assert_eq!(v, iterout);
682     }
683
684     #[test]
685     fn test_top_and_pop() {
686         let data = vec!(2u, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1);
687         let mut sorted = data.clone();
688         sorted.sort();
689         let mut heap = BinaryHeap::from_vec(data);
690         while !heap.is_empty() {
691             assert_eq!(heap.top().unwrap(), sorted.last().unwrap());
692             assert_eq!(heap.pop().unwrap(), sorted.pop().unwrap());
693         }
694     }
695
696     #[test]
697     fn test_push() {
698         let mut heap = BinaryHeap::from_vec(vec!(2i, 4, 9));
699         assert_eq!(heap.len(), 3);
700         assert!(*heap.top().unwrap() == 9);
701         heap.push(11);
702         assert_eq!(heap.len(), 4);
703         assert!(*heap.top().unwrap() == 11);
704         heap.push(5);
705         assert_eq!(heap.len(), 5);
706         assert!(*heap.top().unwrap() == 11);
707         heap.push(27);
708         assert_eq!(heap.len(), 6);
709         assert!(*heap.top().unwrap() == 27);
710         heap.push(3);
711         assert_eq!(heap.len(), 7);
712         assert!(*heap.top().unwrap() == 27);
713         heap.push(103);
714         assert_eq!(heap.len(), 8);
715         assert!(*heap.top().unwrap() == 103);
716     }
717
718     #[test]
719     fn test_push_unique() {
720         let mut heap = BinaryHeap::from_vec(vec!(box 2i, box 4, box 9));
721         assert_eq!(heap.len(), 3);
722         assert!(*heap.top().unwrap() == box 9);
723         heap.push(box 11);
724         assert_eq!(heap.len(), 4);
725         assert!(*heap.top().unwrap() == box 11);
726         heap.push(box 5);
727         assert_eq!(heap.len(), 5);
728         assert!(*heap.top().unwrap() == box 11);
729         heap.push(box 27);
730         assert_eq!(heap.len(), 6);
731         assert!(*heap.top().unwrap() == box 27);
732         heap.push(box 3);
733         assert_eq!(heap.len(), 7);
734         assert!(*heap.top().unwrap() == box 27);
735         heap.push(box 103);
736         assert_eq!(heap.len(), 8);
737         assert!(*heap.top().unwrap() == box 103);
738     }
739
740     #[test]
741     fn test_push_pop() {
742         let mut heap = BinaryHeap::from_vec(vec!(5i, 5, 2, 1, 3));
743         assert_eq!(heap.len(), 5);
744         assert_eq!(heap.push_pop(6), 6);
745         assert_eq!(heap.len(), 5);
746         assert_eq!(heap.push_pop(0), 5);
747         assert_eq!(heap.len(), 5);
748         assert_eq!(heap.push_pop(4), 5);
749         assert_eq!(heap.len(), 5);
750         assert_eq!(heap.push_pop(1), 4);
751         assert_eq!(heap.len(), 5);
752     }
753
754     #[test]
755     fn test_replace() {
756         let mut heap = BinaryHeap::from_vec(vec!(5i, 5, 2, 1, 3));
757         assert_eq!(heap.len(), 5);
758         assert_eq!(heap.replace(6).unwrap(), 5);
759         assert_eq!(heap.len(), 5);
760         assert_eq!(heap.replace(0).unwrap(), 6);
761         assert_eq!(heap.len(), 5);
762         assert_eq!(heap.replace(4).unwrap(), 5);
763         assert_eq!(heap.len(), 5);
764         assert_eq!(heap.replace(1).unwrap(), 4);
765         assert_eq!(heap.len(), 5);
766     }
767
768     fn check_to_vec(mut data: Vec<int>) {
769         let heap = BinaryHeap::from_vec(data.clone());
770         let mut v = heap.clone().into_vec();
771         v.sort();
772         data.sort();
773
774         assert_eq!(v, data);
775         assert_eq!(heap.into_sorted_vec(), data);
776     }
777
778     #[test]
779     fn test_to_vec() {
780         check_to_vec(vec!());
781         check_to_vec(vec!(5i));
782         check_to_vec(vec!(3i, 2));
783         check_to_vec(vec!(2i, 3));
784         check_to_vec(vec!(5i, 1, 2));
785         check_to_vec(vec!(1i, 100, 2, 3));
786         check_to_vec(vec!(1i, 3, 5, 7, 9, 2, 4, 6, 8, 0));
787         check_to_vec(vec!(2i, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1));
788         check_to_vec(vec!(9i, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0));
789         check_to_vec(vec!(0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
790         check_to_vec(vec!(10i, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));
791         check_to_vec(vec!(0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2));
792         check_to_vec(vec!(5i, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1));
793     }
794
795     #[test]
796     fn test_empty_pop() {
797         let mut heap: BinaryHeap<int> = BinaryHeap::new();
798         assert!(heap.pop().is_none());
799     }
800
801     #[test]
802     fn test_empty_top() {
803         let empty: BinaryHeap<int> = BinaryHeap::new();
804         assert!(empty.top().is_none());
805     }
806
807     #[test]
808     fn test_empty_replace() {
809         let mut heap: BinaryHeap<int> = BinaryHeap::new();
810         heap.replace(5).is_none();
811     }
812
813     #[test]
814     fn test_from_iter() {
815         let xs = vec!(9u, 8, 7, 6, 5, 4, 3, 2, 1);
816
817         let mut q: BinaryHeap<uint> = xs.iter().rev().map(|&x| x).collect();
818
819         for &x in xs.iter() {
820             assert_eq!(q.pop().unwrap(), x);
821         }
822     }
823 }