Skip to content

Commit 97250a9

Browse files
[Feat] Add Radix Sort (TheAlgorithms#141)
* feat(sorting): add radix sort * Refactor radix computation in radix_sort Co-authored-by: Konrad Borowski <[email protected]> Co-authored-by: Konrad Borowski <[email protected]>
1 parent 63c2a00 commit 97250a9

File tree

4 files changed

+78
-1
lines changed

4 files changed

+78
-1
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ These are for demonstration purposes only.
1212
- [Insertion](./src/sorting/insertion_sort.rs)
1313
- [Merge](./src/sorting/merge_sort.rs)
1414
- [Quick](./src/sorting/quick_sort.rs)
15-
- Radix _(Not implemented yet)_
15+
- [Radix](./src/sorting/radix_sort.rs)
1616
- [Selection](./src/sorting/selection_sort.rs)
1717
- [Shell](./src/sorting/shell_sort.rs)
1818

src/sorting/README.md

+13
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ __Properties__
6666

6767
###### View the algorithm in [action][quick-toptal]
6868

69+
### [Radix](./radix_sort.rs)
70+
![alt text][radix-image]
71+
72+
From [Wikipedia][radix-wiki]: Radix sort is a non-comparative sorting algorithm. It avoids comparison by creating and distributing elements into buckets according to their radix. For elements with more than one significant digit, this bucketing process is repeated for each digit, while preserving the ordering of the prior step, until all digits have been considered.
73+
74+
__Properties__
75+
* Worst case performance O(w*n)
76+
77+
where w is the number of bits required to store each key.
78+
6979
### [Selection](./selection_sort.rs)
7080
![alt text][selection-image]
7181

@@ -108,6 +118,9 @@ __Properties__
108118
[merge-wiki]: https://en.wikipedia.org/wiki/Merge_sort
109119
[merge-image]: https://upload.wikimedia.org/wikipedia/commons/c/cc/Merge-sort-example-300px.gif "Merge Sort"
110120

121+
[radix-wiki]: https://en.wikipedia.org/wiki/Radix_sort
122+
[radix-image]: https://ds055uzetaobb.cloudfront.net/brioche/uploads/IEZs8xJML3-radixsort_ed.png?width=400 "Radix Sort"
123+
111124
[selection-toptal]: https://www.toptal.com/developers/sorting-algorithms/selection-sort
112125
[selection-wiki]: https://en.wikipedia.org/wiki/Selection_sort
113126
[selection-image]: https://upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Selection_sort_animation.gif/250px-Selection_sort_animation.gif "Selection Sort Sort"

src/sorting/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod heap_sort;
44
mod insertion;
55
mod merge_sort;
66
mod quick_sort;
7+
mod radix_sort;
78
mod selection_sort;
89

910
use std::cmp;
@@ -15,6 +16,7 @@ pub use self::heap_sort::heap_sort;
1516
pub use self::insertion::insertion_sort;
1617
pub use self::merge_sort::merge_sort;
1718
pub use self::quick_sort::quick_sort;
19+
pub use self::radix_sort::radix_sort;
1820
pub use self::selection_sort::selection_sort;
1921

2022
pub fn is_sorted<T>(arr: &[T]) -> bool

src/sorting/radix_sort.rs

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/// Sorts the elements of `arr` in-place using radix sort.
2+
///
3+
/// Time complexity is `O((n + b) * logb(k))`, where `n` is the number of elements,
4+
/// `b` is the base (the radix), and `k` is the largest element.
5+
/// When `n` and `b` are roughly the same maginitude, this algorithm runs in linear time.
6+
///
7+
/// Space complexity is `O(n + b)`.
8+
pub fn radix_sort(arr: &mut [u64]) {
9+
let max: usize = match arr.iter().max() {
10+
Some(&x) => x as usize,
11+
None => return,
12+
};
13+
// Make radix a power of 2 close to arr.len() for optimal runtime
14+
let radix = arr.len().next_power_of_two();
15+
// Counting sort by each digit from least to most significant
16+
let mut place = 1;
17+
while place <= max {
18+
let digit_of = |x| x as usize / place % radix;
19+
// Count digit occurrences
20+
let mut counter = vec![0; radix];
21+
for &x in arr.iter() {
22+
counter[digit_of(x)] += 1;
23+
}
24+
// Compute last index of each digit
25+
for i in 1..radix {
26+
counter[i] += counter[i - 1];
27+
}
28+
// Write elements to their new indices
29+
for &x in arr.to_owned().iter().rev() {
30+
counter[digit_of(x)] -= 1;
31+
arr[counter[digit_of(x)]] = x;
32+
}
33+
place *= radix;
34+
}
35+
}
36+
37+
#[cfg(test)]
38+
mod tests {
39+
use super::super::is_sorted;
40+
use super::radix_sort;
41+
42+
#[test]
43+
fn empty() {
44+
let mut a: [u64; 0] = [];
45+
radix_sort(&mut a);
46+
assert!(is_sorted(&a));
47+
}
48+
49+
#[test]
50+
fn descending() {
51+
let mut v = vec![201, 127, 64, 37, 24, 4, 1];
52+
radix_sort(&mut v);
53+
assert!(is_sorted(&v));
54+
}
55+
56+
#[test]
57+
fn ascending() {
58+
let mut v = vec![1, 4, 24, 37, 64, 127, 201];
59+
radix_sort(&mut v);
60+
assert!(is_sorted(&v));
61+
}
62+
}

0 commit comments

Comments
 (0)