Advertisement
Guest User

Untitled

a guest
Jun 18th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 4.57 KB | None | 0 0
  1. use std::cmp::Ordering;
  2. use std::vec::Vec;
  3.  
  4. fn choose_pivot_position(lower: usize, upper: usize) -> usize {
  5.     return upper + ((lower - upper) / 2);
  6. }
  7.  
  8. fn partition<F, T>(compare: &F, data: &mut [T], lower: usize, upper: usize, p: usize) -> usize
  9. where
  10.     F: Fn(&T, &T) -> Ordering,
  11. {
  12.     unsafe {
  13.         let mut i = upper;
  14.         let mut nextp = upper;
  15.  
  16.         data.swap(lower, p);
  17.  
  18.         while i < lower {
  19.             if compare(data.get_unchecked(i), data.get_unchecked(lower)) == Ordering::Greater {
  20.                 if i != nextp {
  21.                     data.swap(i, nextp);
  22.                 }
  23.                 nextp += 1;
  24.             }
  25.             i += 1;
  26.         }
  27.  
  28.         data.swap(nextp, lower);
  29.         nextp
  30.     }
  31. }
  32.  
  33. fn select<F, T>(
  34.     compare: &F,
  35.     data: &mut Vec<T>,
  36.     partitions: &mut Vec<(usize, usize)>,
  37.     lower: usize,
  38.     upper: usize,
  39. ) -> T
  40. where
  41.     F: Fn(&T, &T) -> Ordering,
  42. {
  43.     // If lower and upper are the same, then just pop the next value
  44.     // If lower and upper are adjacent, then manually swap depending on ordering
  45.     // everything else, do the next stage of a quick sort
  46.     match lower - upper {
  47.         0 => data.pop().expect("Empty vector"),
  48.         1 => unsafe {
  49.             if compare(data.get_unchecked(lower), data.get_unchecked(upper)) == Ordering::Greater {
  50.                 data.swap(lower, upper);
  51.             }
  52.             partitions.push((upper, upper));
  53.             data.pop().expect("Empty vector")
  54.         },
  55.         _ => {
  56.             let p = choose_pivot_position(lower, upper);
  57.             let p = partition(compare, data, lower, upper, p);
  58.             if p == lower {
  59.                 partitions.push((p - 1, upper));
  60.                 select(compare, data, partitions, lower, p)
  61.             } else {
  62.                 partitions.push((p, upper));
  63.                 select(compare, data, partitions, lower, p + 1)
  64.             }
  65.         }
  66.     }
  67. }
  68.  
  69. fn make_first_partition(len: usize) -> Vec<(usize, usize)> {
  70.     let mut partitions = Vec::with_capacity(len / 4);
  71.     if len > 0 {
  72.         partitions.push((len - 1, 0));
  73.     }
  74.     partitions
  75. }
  76.  
  77. pub struct LazySortIterator<T> {
  78.     data: Vec<T>,
  79.     partitions: Vec<(usize, usize)>,
  80. }
  81.  
  82. impl<T> LazySortIterator<T>
  83. where
  84.     T: Ord,
  85. {
  86.     fn new(data: Vec<T>) -> Self {
  87.         let partitions = make_first_partition(data.len());
  88.         Self { data, partitions }
  89.     }
  90.     fn select(&mut self, lower: usize, upper: usize) -> T {
  91.         select(&Ord::cmp, &mut self.data, &mut self.partitions, lower, upper)
  92.     }
  93. }
  94.  
  95. pub struct LazySortIteratorBy<T, F> {
  96.     data: Vec<T>,
  97.     partitions: Vec<(usize, usize)>,
  98.     compare: F,
  99. }
  100.  
  101. impl<T, F> LazySortIteratorBy<T, F>
  102. where
  103.     F: Fn(&T, &T) -> Ordering,
  104. {
  105.     fn new(data: Vec<T>, compare: F) -> Self {
  106.         let partitions = make_first_partition(data.len());
  107.         LazySortIteratorBy {
  108.             data,
  109.             partitions,
  110.             compare,
  111.         }
  112.     }
  113.  
  114.     fn select(&mut self, lower: usize, upper: usize) -> T {
  115.         select(&self.compare, &mut self.data, &mut self.partitions, lower, upper)
  116.     }
  117. }
  118.  
  119. pub trait LazySort {
  120.     type Item: Ord;
  121.  
  122.     fn lazy_sort(self) -> LazySortIterator<Self::Item>;
  123. }
  124.  
  125. pub trait LazySortBy {
  126.     type Item;
  127.  
  128.     fn lazy_sort_by<F>(self, F) -> LazySortIteratorBy<Self::Item, F>
  129.     where
  130.         F: Fn(&Self::Item, &Self::Item) -> Ordering;
  131. }
  132.  
  133. impl<T> LazySort for Vec<T>
  134. where
  135.     T: Eq + Ord,
  136. {
  137.     type Item = T;
  138.  
  139.     fn lazy_sort(self) -> LazySortIterator<T> {
  140.         LazySortIterator::new(self)
  141.     }
  142. }
  143.  
  144. impl<T> LazySortBy for Vec<T> {
  145.     type Item = T;
  146.  
  147.     fn lazy_sort_by<F>(self, compare: F) -> LazySortIteratorBy<T, F>
  148.     where
  149.         F: Fn(&T, &T) -> Ordering,
  150.     {
  151.         LazySortIteratorBy::new(self, compare)
  152.     }
  153. }
  154.  
  155. macro_rules! add_next {
  156.     () => {
  157.         #[inline]
  158.         fn next(&mut self) -> Option<T> {
  159.             match self.partitions.pop() {
  160.                 Some((lower, upper)) => Some(self.select(lower, upper)),
  161.                 None => None
  162.             }
  163.         }
  164.     }
  165. }
  166.  
  167. macro_rules! add_size_hint {
  168.     () => {
  169.         #[inline]
  170.         fn size_hint(&self) -> (usize, Option<usize>) {
  171.             let l = self.data.len();
  172.             (l, Some(l))
  173.         }
  174.     }
  175. }
  176.  
  177. impl<T> Iterator for LazySortIterator<T>
  178. where
  179.     T: Ord,
  180. {
  181.     type Item = T;
  182.  
  183.     add_next!();
  184.     add_size_hint!();
  185. }
  186.  
  187. impl<T, F> Iterator for LazySortIteratorBy<T, F>
  188. where
  189.     F: Fn(&T, &T) -> Ordering,
  190. {
  191.     type Item = T;
  192.  
  193.     add_next!();
  194.     add_size_hint!();
  195. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement