-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1130 from i-vishi/dev
added quick sort, merge, counting sort in Rust
- Loading branch information
Showing
5 changed files
with
162 additions
and
43 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,4 +25,4 @@ function print_array($array) { | |
print_array($array); | ||
bubble_sort($array); | ||
|
||
?> | ||
?> |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/// Counting sort | ||
/// * `arr` - Collection of value to be sorted in place. | ||
/// * `min` - Lower bound of the integer range. | ||
/// * `max` - Upper bound of the integer range. | ||
/// * `key` - Function extracting key witn the integer range from elements. | ||
pub fn counting_sort<F, T>(arr: &mut [T], min: usize, max: usize, key: F) | ||
where | ||
F: Fn(&T) -> usize, | ||
T: Clone, | ||
{ | ||
let mut prefix_sums = { | ||
// 1. Initialize the count array with default value 0. | ||
let len = max - min; | ||
let mut count_arr = Vec::with_capacity(len); | ||
count_arr.resize(len, 0); | ||
|
||
// 2. Scan elements to collect counts. | ||
for value in arr.iter() { | ||
count_arr[key(value)] += 1; | ||
} | ||
|
||
// 3. Calculate prefix sum. | ||
count_arr | ||
.into_iter() | ||
.scan(0, |state, x| { | ||
*state += x; | ||
Some(*state - x) | ||
}) | ||
.collect::<Vec<usize>>() | ||
}; | ||
|
||
// 4. Use prefix sum as index position of output element. | ||
for value in arr.to_vec().iter() { | ||
let index = key(value); | ||
arr[prefix_sums[index]] = value.clone(); | ||
prefix_sums[index] += 1; | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
|
||
mod base { | ||
use super::*; | ||
fn counting_sort_(arr: &mut [i32]) { | ||
counting_sort(arr, 1, 10, |int| *int as usize); | ||
} | ||
base_cases!(counting_sort_); | ||
} | ||
|
||
#[cfg(test)] | ||
|
||
mod stability { | ||
use super::*; | ||
fn counting_sort_(arr: &mut [(i32, i32)]) { | ||
counting_sort(arr, 1, 10, |t| t.0 as usize); | ||
} | ||
stability_cases!(counting_sort_); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
fn merge<T: Copy + PartialOrd>(x1: &[T], x2: &[T], y: &mut [T]) { | ||
assert_eq!(x1.len() + x2.len(), y.len()); | ||
let mut i = 0; | ||
let mut j = 0; | ||
let mut k = 0; | ||
while i < x1.len() && j < x2.len() { | ||
if x1[i] < x2[j] { | ||
y[k] = x1[i]; | ||
k += 1; | ||
i += 1; | ||
} else { | ||
y[k] = x2[j]; | ||
k += 1; | ||
j += 1; | ||
} | ||
} | ||
if i < x1.len() { | ||
y[k..].copy_from_slice(&x1[i..]); | ||
} | ||
if j < x2.len() { | ||
y[k..].copy_from_slice(&x2[j..]); | ||
} | ||
} | ||
|
||
fn merge_sort<T: Copy + Ord>(x: &mut [T]) { | ||
let n = x.len(); | ||
let m = n / 2; | ||
|
||
if n <= 1 { | ||
return; | ||
} | ||
|
||
merge_sort(&mut x[0..m]); | ||
merge_sort(&mut x[m..n]); | ||
|
||
let mut y: Vec<T> = x.to_vec(); | ||
|
||
merge(&x[0..m], &x[m..n], &mut y[..]); | ||
|
||
x.copy_from_slice(&y); | ||
} | ||
|
||
fn main() { | ||
println!("Sort numbers ascending"); | ||
let mut numbers = [4, 65, 2, -31, 0, 99, 2, 83, 782, 1]; | ||
println!("Before: {:?}", numbers); | ||
merge_sort(&mut numbers); | ||
println!("After: {:?}\n", numbers); | ||
|
||
println!("Sort strings alphabetically"); | ||
let mut strings = ["beach", "hotel", "airplane", "car", "house", "art"]; | ||
println!("Before: {:?}", strings); | ||
merge_sort(&mut strings); | ||
println!("After: {:?}\n", strings); | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
pub fn quick_sort<T: Ord>(arr: &mut [T]) { | ||
let len = arr.len(); | ||
_quick_sort(arr, 0, (len - 1) as isize); | ||
} | ||
|
||
fn _quick_sort<T: Ord>(arr: &mut [T], low: isize, high: isize) { | ||
if low < high { | ||
let p = partition(arr, low, high); | ||
_quick_sort(arr, low, p - 1); | ||
_quick_sort(arr, p + 1, high); | ||
} | ||
} | ||
|
||
fn partition<T: Ord>(arr: &mut [T], low: isize, high: isize) -> isize { | ||
let pivot = high as usize; | ||
let mut store_index = low - 1; | ||
let mut last_index = high; | ||
|
||
loop { | ||
store_index += 1; | ||
while arr[store_index as usize] < arr[pivot] { | ||
store_index += 1; | ||
} | ||
last_index -= 1; | ||
while last_index >= 0 && arr[last_index as usize] > arr[pivot] { | ||
last_index -= 1; | ||
} | ||
if store_index >= last_index { | ||
break; | ||
} else { | ||
arr.swap(store_index as usize, last_index as usize); | ||
} | ||
} | ||
arr.swap(store_index as usize, pivot as usize); | ||
store_index | ||
} | ||
fn main() { | ||
println!("Sort numbers ascending"); | ||
let mut numbers = [4, 65, 2, -31, 0, 99, 2, 83, 782, 1]; | ||
println!("Before: {:?}", numbers); | ||
quick_sort(&mut numbers); | ||
println!("After: {:?}\n", numbers); | ||
} |