Created: July, 15, 2023 Last Modified: July, 16, 2023

What Is Merge Sort

Merge Sort is a divide-and-conquer sorting algorithim. This is done by splitting the list into 2 and then continously spliting those lists, until we end up with many 1 length lists. Which are then merged and return to be merged with the other splits. Merge sort is O(n log n)

Merge Sort is good for large list sorting, but can be slower for smaller lists

Quick note: rust actaully has sorting implemented as a trait, vectors can be sorted by calling .sort() on them.

Implementing Merge Sort With Generics, The Merge Part

Merge Sort can seperated into two functions. A merge function that takes two lists and merges them, sorting (in this case smallest to largest); And the main function its self, merge_sort, which will be recursivly called finally calling merge at the end.

Merge compares two lists and takes the smaller value, moving to the next element in list that contained the smaller value. once a list is exhausted the rest of the other list is appended to the end of the out list, if both are exhausted then the out list is returned. Thanks to the Rust Trait system we can write this once as a generic implmentation and get it for all types that have the ParialOrd and Clone trait. ParitalOrd is needed for Comparing the values contained in the vector

        
    fn merge(list1: &Vec, list2: &Vec) -> Vec
    where
        T: PartialOrd + Copy,
    {
        let mut out = vec![];
        let mut i1 = 0;
        let mut i2 = 0;
        while i1 < list1.len() && i2 < list2.len() {
            if list1[i1] < list2[i2] {
                out.push(list1[i1]);
                i1 += 1;
            } else {
                out.push(list2[i2]);
                i2 += 1;
            }
        }
        while i1 < list1.len() {
            out.push(list1[i1]);
            i1 += 1;
        }
        while i2 < list2.len() {
            out.push(list2[i2]);
            i2 += 1;
        }
        out
    }
        
    

The Merge Sort Part

Now we can write the whole merge sort function. Merge sort should return the passed list if the size is less than 2. Otherwise it should split the list and call mergesort and both. Lastly calling merge and returning the resulting list.


pub fn merge_sort(list: &Vec) -> Vec
where
    T: PartialOrd + Copy,
{
    //if vec is less than 2 in len we cant sort
    if list.len() < 2 {
        list.clone()
    } else {
        //split and mergesort each half
        let middle = list.len() / 2;
        let m1 = merge_sort(&list[..middle].to_vec());
        let m2 = merge_sort(&list[middle..].to_vec());
        merge(&m1, &m2)
    }
}
    

With that you now have a merge sort function ready to sort all of your vectors. The full code can be seen below


pub fn merge_sort(list: &Vec) -> Vec
where
    T: PartialOrd + Copy,
{
    //if vec is less than 2 in len we cant sort
    if list.len() < 2 {
        list.clone()
    } else {
        //split and mergesort each half
        let middle = list.len() / 2;
        let m1 = merge_sort(&list[..middle].to_vec());
        let m2 = merge_sort(&list[middle..].to_vec());
        merge(&m1, &m2)
    }
}

fn merge(list1: &Vec, list2: &Vec) -> Vec where T: PartialOrd + Copy, { let mut out = vec![]; let mut i1 = 0; let mut i2 = 0; while i1 < list1.len() && i2 < list2.len() { if list1[i1] < list2[i2] { out.push(list1[i1]); i1 += 1; } else { out.push(list2[i2]); i2 += 1; } } while i1 < list1.len() { out.push(list1[i1]); i1 += 1; } while i2 < list2.len() { out.push(list2[i2]); i2 += 1; } out }

Full Code can be found at   https://github.com/PGIII/rust-algos/blob/main/src/merge_sort.rs