(index<- )        ./libcollections/priority_queue.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   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, nuint) { 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, nuint) {
  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, itemT) {
  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 itemT) -> 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 itemT) -> 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(capacityuint) -> PriorityQueue<T> {
 122          PriorityQueue { data: Vec::with_capacity(capacity) }
 123      }
 124  
 125      /// Create a PriorityQueue from a vector (heapify)
 126      pub fn from_vec(xsVec<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, startuint, mut posuint) {
 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 posuint, enduint) {
 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, posuint) {
 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>>(iterIter) -> 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 iterIter) {
 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  }