Implemented MSD radix sort algorithm in-place (#4449)
* Implemented MSD radix sort algorithm inplace * Fixed formatting
This commit is contained in:
parent
32e9072627
commit
b913a0d83a
@ -74,6 +74,86 @@ def _msd_radix_sort(list_of_ints: List[int], bit_position: int) -> List[int]:
|
||||
return res
|
||||
|
||||
|
||||
def msd_radix_sort_inplace(list_of_ints: List[int]):
|
||||
"""
|
||||
Inplace implementation of the MSD radix sort algorithm.
|
||||
Sorts based on the binary representation of the integers.
|
||||
>>> lst = [1, 345, 23, 89, 0, 3]
|
||||
>>> msd_radix_sort_inplace(lst)
|
||||
>>> lst == sorted(lst)
|
||||
True
|
||||
>>> lst = [1, 43, 0, 0, 0, 24, 3, 3]
|
||||
>>> msd_radix_sort_inplace(lst)
|
||||
>>> lst == sorted(lst)
|
||||
True
|
||||
>>> lst = []
|
||||
>>> msd_radix_sort_inplace(lst)
|
||||
>>> lst == []
|
||||
True
|
||||
>>> lst = [-1, 34, 23, 4, -42]
|
||||
>>> msd_radix_sort_inplace(lst)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: All numbers must be positive
|
||||
"""
|
||||
|
||||
length = len(list_of_ints)
|
||||
if not list_of_ints or length == 1:
|
||||
return
|
||||
|
||||
if min(list_of_ints) < 0:
|
||||
raise ValueError("All numbers must be positive")
|
||||
|
||||
most_bits = max(len(bin(x)[2:]) for x in list_of_ints)
|
||||
_msd_radix_sort_inplace(list_of_ints, most_bits, 0, length)
|
||||
|
||||
|
||||
def _msd_radix_sort_inplace(
|
||||
list_of_ints: List[int], bit_position: int, begin_index: int, end_index: int
|
||||
):
|
||||
"""
|
||||
Sort the given list based on the bit at bit_position. Numbers with a
|
||||
0 at that position will be at the start of the list, numbers with a
|
||||
1 at the end.
|
||||
>>> lst = [45, 2, 32, 24, 534, 2932]
|
||||
>>> _msd_radix_sort_inplace(lst, 1, 0, 3)
|
||||
>>> lst == [32, 2, 45, 24, 534, 2932]
|
||||
True
|
||||
>>> lst = [0, 2, 1, 3, 12, 10, 4, 90, 54, 2323, 756]
|
||||
>>> _msd_radix_sort_inplace(lst, 2, 4, 7)
|
||||
>>> lst == [0, 2, 1, 3, 12, 4, 10, 90, 54, 2323, 756]
|
||||
True
|
||||
"""
|
||||
if bit_position == 0 or end_index - begin_index <= 1:
|
||||
return
|
||||
|
||||
bit_position -= 1
|
||||
|
||||
i = begin_index
|
||||
j = end_index - 1
|
||||
while i <= j:
|
||||
changed = False
|
||||
if not ((list_of_ints[i] >> bit_position) & 1):
|
||||
# found zero at the beginning
|
||||
i += 1
|
||||
changed = True
|
||||
if (list_of_ints[j] >> bit_position) & 1:
|
||||
# found one at the end
|
||||
j -= 1
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
continue
|
||||
|
||||
list_of_ints[i], list_of_ints[j] = list_of_ints[j], list_of_ints[i]
|
||||
j -= 1
|
||||
if not j == i:
|
||||
i += 1
|
||||
|
||||
_msd_radix_sort_inplace(list_of_ints, bit_position, begin_index, i)
|
||||
_msd_radix_sort_inplace(list_of_ints, bit_position, i, end_index)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user