rust_sort/
cocktail_sort.rs

1use super::Sortable;
2
3/// Cocktail sorts in-place, stable, in ascending order a mutable ref slice of type T: Sortable
4///
5/// Cocktail is a variant of bubble sort. It continuously loops over elements in slice collection, swapping elements
6/// if they are out of order. If no swaps occur in a loop then the sort is complete.
7/// Each iteration swaps order of the iteration from left to right and from comparing smallest to largest, such that
8/// the largest and smallest elements are bubbled up and down the list bidirectionally.
9/// It aims to solve the rabbit and turtle problem of standard bubble sort where values that
10/// need to move to the beginning of the list require many swaps to get there.
11///
12/// # Examples
13///
14/// ```
15/// use rust_sort::cocktail_sort::sort;
16///
17/// let mut arr = [3, 2, 1, 7, 9, 4, 1, 2];
18/// sort(&mut arr);
19/// assert_eq!(arr, [1, 1, 2, 2, 3, 4, 7, 9]);
20///
21/// ```
22pub fn sort<T: Sortable>(list: &mut [T]) {
23    let len = list.len();
24    if len <= 1 {
25        return;
26    }
27
28    loop {
29        let mut swapped = false;
30        for i in 0..len - 1 {
31            if list[i] > list[i + 1] {
32                list.swap(i, i + 1);
33                swapped = true;
34            }
35        }
36        if !swapped {
37            break;
38        }
39        for i in (1..len-1).rev() {
40            if list[i] < list[i - 1] {
41                list.swap(i, i - 1);
42                swapped = true;
43            }
44        }
45        if !swapped {
46            break;
47        }
48    }
49}