From 8285a1830c65860a67c538dc8816ef61a741af76 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Wed, 19 May 2021 16:23:53 +0200 Subject: [PATCH 1/5] Added MSD radix sort algorithm --- sorts/msd_radix_sort.py | 69 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 sorts/msd_radix_sort.py diff --git a/sorts/msd_radix_sort.py b/sorts/msd_radix_sort.py new file mode 100644 index 000000000000..f89fe7618cc5 --- /dev/null +++ b/sorts/msd_radix_sort.py @@ -0,0 +1,69 @@ +""" +Python implementation of the MSD radix sort algorithm +""" +from typing import List + + +def msd_radix_sort(list_of_ints: List[int]) -> List[int]: + """ + Implementation of the MSD radix sort algorithm. Only works + with positive integers + :param list_of_ints: A list of integers + :return: Returns the sorted list + >>> msd_radix_sort([40, 12, 1, 100, 4]) + [1, 4, 12, 40, 100] + >>> msd_radix_sort([]) + [] + >>> msd_radix_sort([123, 345, 123, 80]) + [80, 123, 123, 345] + >>> msd_radix_sort([1209, 834598, 1, 540402, 45]) + [1, 45, 1209, 540402, 834598] + """ + if not list_of_ints: + 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) + return _msd_radix_sort(list_of_ints, most_bits) + + +def _msd_radix_sort(list_of_ints: List[int], bit_position: int) -> List[int]: + """ + Sort the given list based of 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. + :param list_of_ints: A list of integers + :param bit_position: a bit which gets compared + :return: Returns a list of integers + """ + if bit_position == 0 or len(list_of_ints) == 1 or len(list_of_ints) == 0: + return list_of_ints + + zeros = list() + ones = list() + # Split numbers based on bit at bit_position from the right + for index, number in enumerate(list_of_ints): + if (number >> (bit_position - 1)) & 1: + # number as a one at bit bit_position + ones.append(number) + else: + # number as a zero at bit bit_position + zeros.append(number) + + # recursively split both lists further + zeros = _msd_radix_sort(zeros, bit_position - 1) + ones = _msd_radix_sort(ones, bit_position - 1) + + # recombine lists + res = zeros + res.extend(ones) + + return res + + +if __name__ == "__main__": + import doctest + + doctest.testmod() From 876fbdce2ca41137cf9243bd014544b7af86c88f Mon Sep 17 00:00:00 2001 From: BuildTools Date: Wed, 19 May 2021 16:27:11 +0200 Subject: [PATCH 2/5] Fixed typos --- sorts/msd_radix_sort.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sorts/msd_radix_sort.py b/sorts/msd_radix_sort.py index f89fe7618cc5..f158f217ae42 100644 --- a/sorts/msd_radix_sort.py +++ b/sorts/msd_radix_sort.py @@ -31,12 +31,12 @@ def msd_radix_sort(list_of_ints: List[int]) -> List[int]: def _msd_radix_sort(list_of_ints: List[int], bit_position: int) -> List[int]: """ - Sort the given list based of the bit at bit_position. Numbers with a + 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. :param list_of_ints: A list of integers - :param bit_position: a bit which gets compared - :return: Returns a list of integers + :param bit_position: the position of the bit that gets compared + :return: Returns a partially sorted list """ if bit_position == 0 or len(list_of_ints) == 1 or len(list_of_ints) == 0: return list_of_ints @@ -46,10 +46,10 @@ def _msd_radix_sort(list_of_ints: List[int], bit_position: int) -> List[int]: # Split numbers based on bit at bit_position from the right for index, number in enumerate(list_of_ints): if (number >> (bit_position - 1)) & 1: - # number as a one at bit bit_position + # number has a one at bit bit_position ones.append(number) else: - # number as a zero at bit bit_position + # number has a zero at bit bit_position zeros.append(number) # recursively split both lists further From 2b7227d3938af4f9c5739fca1cbf5b3abba510c2 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Wed, 19 May 2021 16:38:18 +0200 Subject: [PATCH 3/5] Added doctests --- sorts/msd_radix_sort.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sorts/msd_radix_sort.py b/sorts/msd_radix_sort.py index f158f217ae42..a2d38c5acf71 100644 --- a/sorts/msd_radix_sort.py +++ b/sorts/msd_radix_sort.py @@ -37,6 +37,10 @@ def _msd_radix_sort(list_of_ints: List[int], bit_position: int) -> List[int]: :param list_of_ints: A list of integers :param bit_position: the position of the bit that gets compared :return: Returns a partially sorted list + >>> _msd_radix_sort([45, 2, 32], 1) + [2, 32, 45] + >>> _msd_radix_sort([10, 4, 12], 2) + [4, 12, 10] """ if bit_position == 0 or len(list_of_ints) == 1 or len(list_of_ints) == 0: return list_of_ints From 31cb885e318586cd585deb3f6bccd51248ff2a00 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Wed, 19 May 2021 16:45:31 +0200 Subject: [PATCH 4/5] Added link to wikipedia --- sorts/msd_radix_sort.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sorts/msd_radix_sort.py b/sorts/msd_radix_sort.py index a2d38c5acf71..1e13c560ba69 100644 --- a/sorts/msd_radix_sort.py +++ b/sorts/msd_radix_sort.py @@ -1,5 +1,8 @@ """ -Python implementation of the MSD radix sort algorithm +Python implementation of the MSD radix sort algorithm. +It used the binary representation of the integers to sort +them. +https://en.wikipedia.org/wiki/Radix_sort """ from typing import List From 2412139844e5d7148f79fb4729ee12e416cd092d Mon Sep 17 00:00:00 2001 From: BuildTools Date: Thu, 20 May 2021 15:43:37 +0200 Subject: [PATCH 5/5] Added doctest and improved code --- sorts/msd_radix_sort.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sorts/msd_radix_sort.py b/sorts/msd_radix_sort.py index 1e13c560ba69..ee152bbc696a 100644 --- a/sorts/msd_radix_sort.py +++ b/sorts/msd_radix_sort.py @@ -21,6 +21,10 @@ def msd_radix_sort(list_of_ints: List[int]) -> List[int]: [80, 123, 123, 345] >>> msd_radix_sort([1209, 834598, 1, 540402, 45]) [1, 45, 1209, 540402, 834598] + >>> msd_radix_sort([-1, 34, 45]) + Traceback (most recent call last): + ... + ValueError: All numbers must be positive """ if not list_of_ints: return [] @@ -45,13 +49,13 @@ def _msd_radix_sort(list_of_ints: List[int], bit_position: int) -> List[int]: >>> _msd_radix_sort([10, 4, 12], 2) [4, 12, 10] """ - if bit_position == 0 or len(list_of_ints) == 1 or len(list_of_ints) == 0: + if bit_position == 0 or len(list_of_ints) in [0, 1]: return list_of_ints zeros = list() ones = list() # Split numbers based on bit at bit_position from the right - for index, number in enumerate(list_of_ints): + for number in list_of_ints: if (number >> (bit_position - 1)) & 1: # number has a one at bit bit_position ones.append(number)