Skip to content

Commit 34db0c5

Browse files
committed
Added ksort algorithm, bumped version and edited docs
1 parent 51739bd commit 34db0c5

File tree

5 files changed

+105
-5
lines changed

5 files changed

+105
-5
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sorting_rs"
3-
version = "1.2.2"
3+
version = "1.2.3"
44
authors = ["flakusha <[email protected]>"]
55
edition = "2018"
66
repository = "https://github.com/flakusha/rust_sorting"

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ please read modules documentation
2020
New algorithms implementations are planned
2121

2222
| Sorting algorithm | Features and downsides | Worst-case performance O(): comparisons; swaps | Best-case performance O(): comparisons; swaps | Space complexity O() |
23-
| ------ | -------------------------------- | ------------------------------------ | -------- | ---------- |
23+
| -------------- | -------------------------------- | -------- | -------- | ------------- |
2424
| Bubble | bad for sorted or reversed input | `n`<sup>`2`</sup>; `n`<sup>`2`</sup> | `n`; `1` | `n` or `1` |
2525
| Cocktail | little performance improvement over bubble sort | `n`<sup>`2`</sup> | `n` | `1` |
2626
| Comb | speeds up when data is nearly sorted | `n`<sup>`2`</sup> | `nlogn` | `1` |
@@ -33,7 +33,8 @@ New algorithms implementations are planned
3333
| Merge | independent of data distribution | `nlogn` | `nlogn` or `n` | `n` |
3434
| Odd-even | presented to be effective on processors with local interconnections | `n`<sup>`2`</sup> | `n` | `1` |
3535
| Odd-even (Batcher) | more efficient version of odd-even sort | `log`<sup>`2`</sup>`n` | `log`<sup>`2`</sup>`n` | `log`<sup>`2`</sup>`n` |
36-
| Quick | bad for sorted or reversed input | `n`<sup>`2`</sup> | `n` | `n` or `logn` |
36+
| Quick | bad for sorted or reversed input | `n`<sup>`2`</sup> | `nlog`<sub>2</sub>`n` | `n` or `logn` |
37+
| Ksort | modified version of quicksort, faster than heap at less than 7 million elements | `n`<sup>`2`</sup> | `nlog`<sub>2</sub>`n` | `n` or `logn` |
3738
| Selection | the least number of swaps among all the algorithms | `n`<sup>`2`</sup>; `n` | `n`<sup>`2`</sup>; `1` | `1` |
3839
| Shell | it is optimization of insertion sort | `n`<sup>`2`</sup> or `nlog`<sup>`2`</sup>`n` | `nlogn` or `nlog`<sup>`2`</sup>`n` | `n` |
3940
| Slow | it's slow, who would ever need it? | | | |

benches/sort_benchmark.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ macro_rules! create_bench {
3030
}
3131

3232
fn bench(c: &mut Criterion) {
33-
let sizes: Vec<usize> = vec![10, 100, 1000, 10_000, /*100_000, 1_000_000,
33+
let sizes: Vec<usize> = vec![10, 100, 1000, 10_000, 100_000, /* 1_000_000,
3434
10_000_000*/];
3535

3636
let benchmark = create_bench! {
@@ -43,6 +43,7 @@ fn bench(c: &mut Criterion) {
4343
heap_bottom_up_sort,
4444
weak_heap_sort,
4545
insertion_sort,
46+
ksort,
4647
merge_sort,
4748
nheap_sort,
4849
oddeven_sort,

src/ksort.rs

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/// Sorts a slice in-place using
2+
/// [K-sort](https://arxiv.org/abs/1107.3622)
3+
///
4+
/// This sorting algorithm is in fact a modification of quick sort which should
5+
/// be faster than quicksort for arrays with less than 7 million elements
6+
/// This algorithm is generally compared to heapsort and quicksort, it doesn't
7+
/// need to construct the heap and generally wins in benchmarks because of this
8+
///
9+
/// # Examples
10+
/// ```rust
11+
/// let mut vec = vec![5, 2, 7, 3, 9];
12+
/// sorting_rs::ksort(&mut vec);
13+
/// debug_assert_eq!(vec, &[2, 3, 5, 7, 9]);
14+
/// ```
15+
/// ```rust
16+
/// let mut strings = vec!["rustc", "cargo", "rustup"];
17+
/// sorting_rs::ksort(&mut strings);
18+
/// assert_eq!(strings, &["cargo", "rustc", "rustup"]);
19+
/// ```
20+
21+
pub fn ksort<T: PartialOrd + Clone + Copy>(input: &mut [T]) {
22+
if input.len() < 2 {return;}
23+
ksort_lr(input, 0, input.len() - 1);
24+
}
25+
26+
fn ksort_lr<T: PartialOrd + Clone + Copy>(input: &mut [T], left: usize,
27+
right: usize) {
28+
let key = input[left].clone();
29+
// just init it, so no unsafe calls needed, otherwise use of uninit
30+
// is prohibited by Rust compiler
31+
let mut temp = key.clone();
32+
let mut i = left;
33+
let mut j = right + 1;
34+
let mut k = i + 1;
35+
let mut p = i + 1;
36+
let mut flag = false;
37+
38+
while j - i >= 2 {
39+
if key <= input[p] {
40+
if p != j && j != right + 1 {
41+
input.swap(j, p);
42+
} else if j == right + 1 {
43+
flag = true;
44+
temp = input[p].clone();
45+
}
46+
j -= 1;
47+
p = j;
48+
} else {
49+
input.swap(i, p);
50+
i += 1;
51+
k += 1;
52+
p = k;
53+
}
54+
}
55+
56+
input[i] = key;
57+
if flag {input[i + 1] = temp;}
58+
59+
if left < i.saturating_sub(1) {
60+
ksort_lr(input, left, i - 1);
61+
}
62+
if right > i + 1 {
63+
ksort_lr(input, i + 1, right);
64+
}
65+
}
66+
67+
#[cfg(test)]
68+
mod tests {
69+
use super::*;
70+
71+
#[test]
72+
fn test_ksort() {
73+
let mut vector_in = [10, 20, 11, 24];
74+
ksort(&mut vector_in);
75+
debug_assert_eq!(vector_in, [10, 11, 20, 24]);
76+
}
77+
#[test]
78+
fn test_ksort_01() {
79+
let mut vector_in = [10, 9, 20, 22, 11, 21, 12, 24, 4, 6, 3];
80+
ksort(&mut vector_in);
81+
debug_assert_eq!(vector_in, [3, 4, 6, 9, 10, 11, 12, 20, 21, 22, 24]);
82+
}
83+
#[test]
84+
fn test_ksort_empty() {
85+
let mut vector_in:Vec<i32> = vec![];
86+
ksort(&mut vector_in);
87+
debug_assert_eq!(vector_in, &[]);
88+
}
89+
#[test]
90+
fn test_ksort_len1() {
91+
let mut vector_in = vec![1];
92+
ksort(&mut vector_in);
93+
debug_assert_eq!(vector_in, vec![1]);
94+
}
95+
}

src/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
//! | Merge | independent of data distribution | `nlogn` | `nlogn` or `n` | `n` |
1515
//! | Odd-even | presented to be effective on processors with local interconnections | `n`<sup>`2`</sup> | `n` | `1` |
1616
//! | Odd-even (Batcher) | more efficient version of odd-even sort | `log`<sup>`2`</sup>`n` | `log`<sup>`2`</sup>`n` | `log`<sup>`2`</sup>`n` |
17-
//! | Quick | bad for sorted or reversed input | `n`<sup>`2`</sup> | `n` | `n` or `logn` |
17+
//! | Quick | bad for sorted or reversed input | `n`<sup>`2`</sup> | `nlog`<sub>2</sub>`n` | `n` or `logn` |
18+
//! | Ksort | modified version of quicksort, faster than heap at less than 7 million elements | `n`<sup>`2`</sup> | `nlog`<sub>2</sub>`n` | `n` or `logn` |
1819
//! | Selection | the least number of swaps among all the algorithms | `n`<sup>`2`</sup>; `n` | `n`<sup>`2`</sup>; `1` | `1` |
1920
//! | Shell | it is optimization of insertion sort | `n`<sup>`2`</sup> or `nlog`<sup>`2`</sup>`n` | `nlogn` or `nlog`<sup>`2`</sup>`n` | `n` |
2021
//! | Slow | it's slow, who would ever need it? | | | |
@@ -27,6 +28,7 @@ pub mod comb_sort;
2728
pub mod gnome_sort;
2829
pub mod heap_sort;
2930
pub mod insertion_sort;
31+
pub mod ksort;
3032
pub mod merge_sort;
3133
pub mod nheap_sort;
3234
pub mod oddeven_sort;
@@ -44,6 +46,7 @@ pub use self::gnome_sort::gnome_sort;
4446
pub use self::heap_sort::{heap_sort, heap_bottom_up_sort, weak_heap_sort};
4547
pub use self::nheap_sort::nheap_sort;
4648
pub use self::insertion_sort::insertion_sort;
49+
pub use self::ksort::ksort;
4750
pub use self::merge_sort::merge_sort;
4851
pub use self::oddeven_sort::{oddeven_sort, oddeven_batcher_sort};
4952
pub use self::quick_sort::quick_sort;

0 commit comments

Comments
 (0)