Skip to content

Commit b11e531

Browse files
authored
Added implementation for MSD radix sort algorithm based on binary representation (#4441)
* Added MSD radix sort algorithm * Fixed typos * Added doctests * Added link to wikipedia * Added doctest and improved code
1 parent 368ce7a commit b11e531

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

sorts/msd_radix_sort.py

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
"""
2+
Python implementation of the MSD radix sort algorithm.
3+
It used the binary representation of the integers to sort
4+
them.
5+
https://en.wikipedia.org/wiki/Radix_sort
6+
"""
7+
from typing import List
8+
9+
10+
def msd_radix_sort(list_of_ints: List[int]) -> List[int]:
11+
"""
12+
Implementation of the MSD radix sort algorithm. Only works
13+
with positive integers
14+
:param list_of_ints: A list of integers
15+
:return: Returns the sorted list
16+
>>> msd_radix_sort([40, 12, 1, 100, 4])
17+
[1, 4, 12, 40, 100]
18+
>>> msd_radix_sort([])
19+
[]
20+
>>> msd_radix_sort([123, 345, 123, 80])
21+
[80, 123, 123, 345]
22+
>>> msd_radix_sort([1209, 834598, 1, 540402, 45])
23+
[1, 45, 1209, 540402, 834598]
24+
>>> msd_radix_sort([-1, 34, 45])
25+
Traceback (most recent call last):
26+
...
27+
ValueError: All numbers must be positive
28+
"""
29+
if not list_of_ints:
30+
return []
31+
32+
if min(list_of_ints) < 0:
33+
raise ValueError("All numbers must be positive")
34+
35+
most_bits = max(len(bin(x)[2:]) for x in list_of_ints)
36+
return _msd_radix_sort(list_of_ints, most_bits)
37+
38+
39+
def _msd_radix_sort(list_of_ints: List[int], bit_position: int) -> List[int]:
40+
"""
41+
Sort the given list based on the bit at bit_position. Numbers with a
42+
0 at that position will be at the start of the list, numbers with a
43+
1 at the end.
44+
:param list_of_ints: A list of integers
45+
:param bit_position: the position of the bit that gets compared
46+
:return: Returns a partially sorted list
47+
>>> _msd_radix_sort([45, 2, 32], 1)
48+
[2, 32, 45]
49+
>>> _msd_radix_sort([10, 4, 12], 2)
50+
[4, 12, 10]
51+
"""
52+
if bit_position == 0 or len(list_of_ints) in [0, 1]:
53+
return list_of_ints
54+
55+
zeros = list()
56+
ones = list()
57+
# Split numbers based on bit at bit_position from the right
58+
for number in list_of_ints:
59+
if (number >> (bit_position - 1)) & 1:
60+
# number has a one at bit bit_position
61+
ones.append(number)
62+
else:
63+
# number has a zero at bit bit_position
64+
zeros.append(number)
65+
66+
# recursively split both lists further
67+
zeros = _msd_radix_sort(zeros, bit_position - 1)
68+
ones = _msd_radix_sort(ones, bit_position - 1)
69+
70+
# recombine lists
71+
res = zeros
72+
res.extend(ones)
73+
74+
return res
75+
76+
77+
if __name__ == "__main__":
78+
import doctest
79+
80+
doctest.testmod()

0 commit comments

Comments
 (0)