1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
#![stable] //! This module contains the implementation of a pivot-based sorting algorithm. //! //! This is used to sort the output of the indexing algorithm, making the final output of the //! program more readable to humans. use std::cmp; /// Trait to mark a sortable implementation. /// /// Intended for use with [`pivot_sort_high_to_low`](fn.pivot_sort_high_to_low.html) /// /// # Examples /// /// ``` /// use lib_word_count::pivot_sort::Sortable; /// /// struct Something { /// x: i64, /// } /// /// impl Sortable for Something { /// fn weight(&self) -> i64 { /// self.x /// } /// } /// /// let something = Something{ /// x: 2 /// }; /// /// assert_eq!(something.weight(), 2i64); /// ``` #[stable] pub trait Sortable { /// The value to sort by. #[stable] fn weight(&self) -> i64; } /// Sort a given vector from highest 'weight' to lowest 'weight'. /// /// Order is derived from the return-value of `weight()`. /// /// # Arguments /// /// * `items` A reference to a vector containing items that implement the Sortable trait. The items /// will be sorted on the vector itself. /// /// # Examples /// /// ``` /// use lib_word_count::pivot_sort; /// # use std::cmp; /// # #[derive(Debug, PartialEq)] /// # struct Something { /// # weight: i64, /// # id: i64 /// # } /// # impl pivot_sort::Sortable for Something { /// # fn weight(&self) -> i64 { /// # self.weight /// # } /// # } /// // We use id to distinguish the order of objects with eual weight. /// let mut sort_me = vec![ /// Something{weight: 5, id: 1}, /// Something{weight: 2, id: 1}, /// Something{weight: 1, id: 1}, /// Something{weight: 3, id: 1}, /// Something{weight: 2, id: 2}, /// Something{weight: 5, id: 2}, /// Something{weight: 4, id: 1}, /// ]; /// /// pivot_sort::pivot_sort_high_to_low(&mut sort_me); /// /// assert_eq!(sort_me, vec![ /// Something{weight: 5, id: 1}, /// Something{weight: 5, id: 2}, /// Something{weight: 4, id: 1}, /// Something{weight: 3, id: 1}, /// Something{weight: 2, id: 1}, /// Something{weight: 2, id: 2}, /// Something{weight: 1, id: 1}, /// ]); /// ``` #[stable] pub fn pivot_sort_high_to_low<'a, T: Sortable>(items: &mut Vec<T>) { if items.len() == 0 { return; } let pivot = match items.pop() { Some(valid_pivot) => valid_pivot, None => unreachable!(), }; let pivot_weight = pivot.weight(); let lower: &mut Vec<T> = &mut Vec::new(); let higher: &mut Vec<T> = &mut Vec::new(); let equal: &mut Vec<T> = &mut vec![pivot]; while let Some(item) = items.pop() { match item.weight().cmp(&pivot_weight) { cmp::Ordering::Less => lower.insert(0, item), cmp::Ordering::Equal => equal.insert(0, item), cmp::Ordering::Greater => higher.insert(0, item), } } pivot_sort_high_to_low(higher); pivot_sort_high_to_low(lower); items.append(higher); items.append(equal); items.append(lower); }