Last active
February 3, 2020 09:36
-
-
Save smertelny/38f9935e89db0ad5f3c4de4484f24b0b to your computer and use it in GitHub Desktop.
Rust merge sort
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #[inline] | |
| fn merge<T>(left: &mut [T], right: &mut [T]) -> Vec<T> | |
| where T: PartialOrd + Copy + Default | |
| { | |
| let mut array:Vec<T> = vec![T::default(); left.len() + right.len()]; | |
| let (mut left_idx, mut right_idx, mut idx) = (0, 0, 0); | |
| while left_idx < left.len() && right_idx < right.len() { | |
| if left[left_idx] != left[left_idx] { | |
| array[idx] = right[right_idx]; | |
| right_idx += 1; | |
| } else if left[left_idx] > right[right_idx] { | |
| array[idx] = right[right_idx]; | |
| right_idx += 1; | |
| } else { | |
| array[idx] = left[left_idx]; | |
| left_idx += 1; | |
| } | |
| idx += 1; | |
| } | |
| while left_idx < left.len() { | |
| array[idx] = left[left_idx]; | |
| left_idx += 1; | |
| idx += 1; | |
| } | |
| while right_idx < right.len() { | |
| array[idx] = right[right_idx]; | |
| right_idx += 1; | |
| idx += 1; | |
| } | |
| array | |
| } | |
| pub fn merge_sort<T>(array: &mut [T]) | |
| where T: PartialOrd + Copy + Default | |
| { | |
| if array.len() <= 1 { | |
| return; | |
| } | |
| let (left, right) = array.split_at_mut(array.len() / 2); | |
| merge_sort(left); | |
| merge_sort(right); | |
| let results = merge(left, right); | |
| array.copy_from_slice(&*results); | |
| } | |
| #[cfg(test)] | |
| mod tests { | |
| use super::*; | |
| #[test] | |
| fn no_elements() { | |
| let mut arr: [i32; 0] = []; | |
| merge_sort(&mut arr); | |
| assert!(arr == []); | |
| } | |
| #[test] | |
| fn single_element() { | |
| let mut arr = [1_i32]; | |
| merge_sort(&mut arr); | |
| assert!(arr == [1_i32]); | |
| } | |
| #[test] | |
| fn already_sorted() { | |
| let mut arr = [1_u8, 2, 3, 10, 20, 100]; | |
| merge_sort(&mut arr); | |
| assert_eq!(arr, [1_u8, 2, 3, 10, 20, 100]); | |
| } | |
| #[test] | |
| fn multiple_elements() { | |
| let mut arr = [2_i32, 1]; | |
| merge_sort(&mut arr); | |
| assert!(arr == [1_i32, 2]); | |
| let mut arr = [5_u32, 4, 87, 55, 2, 56]; | |
| merge_sort(&mut arr); | |
| assert!(arr == [2, 4, 5, 55, 56, 87]); | |
| } | |
| #[test] | |
| fn multiple_float_elements() { | |
| let mut arr = [2.0, 3.5, 1.1, 1.2]; | |
| merge_sort(&mut arr); | |
| assert!(arr == [1.1, 1.2, 2.0, 3.5]); | |
| } | |
| #[test] | |
| fn multiple_with_negative() { | |
| let mut arr = [1, 3, 6, -2]; | |
| merge_sort(&mut arr); | |
| assert!(arr == [-2, 1, 3, 6]); | |
| } | |
| #[test] | |
| fn multiple_floats_with_negative() { | |
| let mut arr = [1., 6.8, 1.544, -3.45]; | |
| merge_sort(&mut arr); | |
| assert_eq!(arr, [-3.45, 1., 1.544, 6.8]); | |
| } | |
| #[test] | |
| fn with_nan() { | |
| let mut arr = [1., std::f32::NAN, 2.]; | |
| let expected_result = [1., 2., std::f32::NAN]; | |
| merge_sort(&mut arr); | |
| for (idx, elem) in arr.iter().enumerate() { | |
| if elem != elem && expected_result[idx] != expected_result[idx] { | |
| continue; | |
| } | |
| assert_eq!(*elem, expected_result[idx]); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment