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