Skip to content

Commit 5d3a6d7

Browse files
implemented Timsort
1 parent 4314f35 commit 5d3a6d7

2 files changed

Lines changed: 115 additions & 0 deletions

File tree

src/sorts/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mod quick;
1818
mod selection;
1919
mod shell;
2020
mod stooge;
21+
mod tim;
2122
mod wiggle;
2223

2324
pub use bead::*;
@@ -38,4 +39,5 @@ pub use quick::*;
3839
pub use selection::*;
3940
pub use shell::*;
4041
pub use stooge::*;
42+
pub use tim::*;
4143
pub use wiggle::*;

src/sorts/tim.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
use core::cmp::min;
2+
3+
use alloc::vec;
4+
5+
/// Timsort implementation in Rust.
6+
///
7+
/// Timsort is a hybrid sorting algorithm derived from merge sort and insertion sort.
8+
/// It works by dividing the array into small chunks (runs) and sorting them using
9+
/// insertion sort, then merging these sorted runs using a modified merge process.
10+
///
11+
/// Complexity:
12+
/// - **Best case:** O(n) when the array is already sorted.
13+
/// - **Average case:** O(n log n).
14+
/// - **Worst case:** O(n log n).
15+
///
16+
/// For more details, visit:
17+
/// [Wikipedia - Timsort](https://en.wikipedia.org/wiki/Timsort)
18+
///
19+
/// # Parameters
20+
/// - `arr`: A mutable slice of elements to be sorted.
21+
///
22+
/// # Type Constraints
23+
/// - `T`: Clone + PartialOrd + Default.
24+
///
25+
/// # Example Usage
26+
/// ```
27+
/// use algoritmer::sorts::tim;
28+
///
29+
/// let mut array = vec![5, 2, 9, 1, 5, 6];
30+
/// tim(&mut array);
31+
/// assert_eq!(array, vec![1, 2, 5, 5, 6, 9]);
32+
/// ```
33+
pub fn tim<T: Clone + PartialOrd + Default>(arr: &mut [T]) {
34+
let n = arr.len();
35+
let run = 32;
36+
37+
for i in (0..n).step_by(run) {
38+
let right = min(i + run - 1, n - 1);
39+
insertion_sort(arr, i, right);
40+
}
41+
42+
let mut size = run;
43+
while size < n {
44+
let mut left = 0;
45+
while left < n {
46+
let mid = left + size - 1;
47+
let right = min(left + 2 * size - 1, n - 1);
48+
49+
if mid < right {
50+
merge(arr, left, mid, right);
51+
}
52+
53+
left += 2 * size;
54+
}
55+
size *= 2;
56+
}
57+
}
58+
59+
fn insertion_sort<T: Clone + PartialOrd>(arr: &mut [T], left: usize, right: usize) {
60+
for i in (left + 1)..=right {
61+
let tmp = arr[i].clone();
62+
let mut j = i;
63+
64+
while j > left && arr[j - 1] > tmp {
65+
arr[j] = arr[j - 1].clone();
66+
j -= 1;
67+
}
68+
69+
arr[j] = tmp;
70+
}
71+
}
72+
73+
fn merge<T: Default + Clone + PartialOrd>(arr: &mut [T], l: usize, m: usize, r: usize) {
74+
let (mut x, mut y, mut i, mut j, mut k) = (0, 0, 0, 0, 0);
75+
let len1: usize = m - l + 1;
76+
let len2 = r - m;
77+
let mut left = vec![T::default(); len1];
78+
let mut right = vec![T::default(); len2];
79+
80+
while x < len1 {
81+
left[x] = arr[l + x].clone();
82+
x += 1;
83+
}
84+
85+
while y < len2 {
86+
right[y] = arr[(m + 1) + y].clone();
87+
y += 1;
88+
}
89+
90+
while i < len1 && j < len2 {
91+
if left[i] <= right[j] {
92+
arr[l + k] = left[i].clone();
93+
i += 1;
94+
} else {
95+
arr[l + k] = right[j].clone();
96+
j += 1;
97+
}
98+
99+
k += 1;
100+
}
101+
102+
while i < len1 {
103+
arr[l + k] = left[i].clone();
104+
k += 1;
105+
i += 1;
106+
}
107+
108+
while j < len2 {
109+
arr[l + k] = right[j].clone();
110+
k += 1;
111+
j += 1;
112+
}
113+
}

0 commit comments

Comments
 (0)