Skip to content

Instantly share code, notes, and snippets.

@smertelny
Last active February 3, 2020 09:36
Show Gist options
  • Select an option

  • Save smertelny/38f9935e89db0ad5f3c4de4484f24b0b to your computer and use it in GitHub Desktop.

Select an option

Save smertelny/38f9935e89db0ad5f3c4de4484f24b0b to your computer and use it in GitHub Desktop.
Rust merge sort
#[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