Skip to content

Commit

Permalink
merge_sort
Browse files Browse the repository at this point in the history
  • Loading branch information
Okm165 committed Dec 29, 2023
1 parent 64405d9 commit d441e45
Show file tree
Hide file tree
Showing 4 changed files with 3,405 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/common.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod math;
mod array_print;
mod array_extend;
mod consts;
mod merge_sort;

#[cfg(test)]
mod tests;
79 changes: 79 additions & 0 deletions src/common/merge_sort.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use cairo_verifier::common::array_extend::ArrayExtendTrait;

// Merge Sort
/// # Arguments
/// * `arr` - Array to sort
/// # Returns
/// * `Array<T>` - Sorted array
fn merge_sort<T, +Copy<T>, +Drop<T>, +PartialOrd<T>>(arr: Array<T>) -> Array<T> {
let len = arr.len();
if len <= 1 {
return arr;
}

// Create left and right arrays
let middle = len / 2;
let (mut left_arr, mut right_arr) = split_array(arr, middle);

// Recursively sort the left and right arrays
let mut sorted_left = merge_sort(left_arr);
let mut sorted_right = merge_sort(right_arr);

let mut result_arr = array![];
merge_recursive(sorted_left, sorted_right, ref result_arr, 0, 0);
result_arr
}

// Merge two sorted arrays
/// # Arguments
/// * `left_arr` - Left array
/// * `right_arr` - Right array
/// * `result_arr` - Result array
/// * `left_arr_ix` - Left array index
/// * `right_arr_ix` - Right array index
/// # Returns
/// * `Array<usize>` - Sorted array
fn merge_recursive<T, +Copy<T>, +Drop<T>, +PartialOrd<T>>(
mut left_arr: Array<T>,
mut right_arr: Array<T>,
ref result_arr: Array<T>,
left_arr_ix: usize,
right_arr_ix: usize
) {
if result_arr.len() == left_arr.len() + right_arr.len() {
return;
}

if left_arr_ix == left_arr.len() {
result_arr.append(*right_arr[right_arr_ix]);
return merge_recursive(left_arr, right_arr, ref result_arr, left_arr_ix, right_arr_ix + 1);
}

if right_arr_ix == right_arr.len() {
result_arr.append(*left_arr[left_arr_ix]);
return merge_recursive(left_arr, right_arr, ref result_arr, left_arr_ix + 1, right_arr_ix);
}

if *left_arr[left_arr_ix] < *right_arr[right_arr_ix] {
result_arr.append(*left_arr[left_arr_ix]);
merge_recursive(left_arr, right_arr, ref result_arr, left_arr_ix + 1, right_arr_ix)
} else {
result_arr.append(*right_arr[right_arr_ix]);
merge_recursive(left_arr, right_arr, ref result_arr, left_arr_ix, right_arr_ix + 1)
}
}

// Split an array into two arrays.
/// * `arr` - The array to split.
/// * `index` - The index to split the array at.
/// # Returns
/// * `(Array<T>, Array<T>)` - The two arrays.
fn split_array<T, +Copy<T>, +Drop<T>>(arr: Array<T>, index: usize) -> (Array<T>, Array<T>) {
let mut arr1 = array![];
let mut arr2 = array![];

arr1.extend(arr.span().slice(0, index));
arr2.extend(arr.span().slice(index, arr.len() - index));

(arr1, arr2)
}
1 change: 1 addition & 0 deletions src/common/tests.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ mod test_from_span;
mod test_horner_eval;
mod test_array_append;
mod test_math;
mod test_merge_sort;
Loading

0 comments on commit d441e45

Please sign in to comment.