median_three_quicksort/
quicksort.rs

1///Taking three random index values determine a starting pivot.
2///Once the starting pivot is setup the initial partition is done
3///with the pivot location returned.
4///Using the pivot location begin with the left partition
5///and sort values in place. Once the left partition is sorted
6///then the right partition is sorted. Repeat until left is
7///greater than right.
8
9use uniq_vec;
10
11fn median_three<T: Ord>(vals: &mut [T]) {
12    //Instead of a median from left, right and middle
13    //this implementation picks three random indices and
14    //compares the values to find a median for use as the
15    //initial pivot value.
16    let rand_idx = uniq_vec::new_vec(3, 1, vals.len());
17
18    let median = 
19        if vals[rand_idx[0]] > vals[rand_idx[1]] &&
20        vals[rand_idx[0]] < vals[rand_idx[2]] {
21            rand_idx[0]
22        } else if vals[rand_idx[1]] > vals[rand_idx[0]] &&
23        vals[rand_idx[1]] < vals[rand_idx[2]] {
24            rand_idx[1]
25        } else {
26            rand_idx[2]
27        };
28
29    vals.swap(0, median);
30}
31
32
33fn partition<T: Ord>(array: &mut [T], left: usize, right: usize) -> usize{
34    //Move values to the left relative to the pivot value sorting the collection.
35    let mut pivot = left;
36
37    for i in left+1..right+1 {
38        if array[i] <= array[left] {
39            pivot += 1;
40            array.swap(i, pivot);
41        }
42    }
43    array.swap(pivot, left);
44
45    //If the vec starts with the lowest number in position 0 then the
46    //the first left pass _quicksort call after partition will fail due
47    //to an overflow caused by 0 - 1.
48
49    let pivot = match pivot {
50        0 => 1,
51        _ => pivot
52    };
53    pivot
54}
55
56fn _quicksort<T: Ord>(array: &mut [T], left: usize, right: usize) {
57    //Check if left is greater than right at which point the
58    //collection has been sorted in place.
59    if left >= right {
60        return
61    }
62
63    let pivot_position = partition(array, left, right);
64    _quicksort(array, left, pivot_position -1);
65    _quicksort(array, pivot_position + 1, right)
66}
67
68pub fn quicksort<T: Ord>(unsorted_vec: &mut [T]) {
69    //check vec length and return if not long enough to sort.
70    //consider how to change up to use references and no 
71
72    if unsorted_vec.len () <= 1 {
73        return
74    } else {
75        let right = unsorted_vec.len() - 1;
76        median_three(unsorted_vec);
77        _quicksort(unsorted_vec, 0, right);
78    }
79}
80