Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions radix_sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""This module contains the radix sort method (radix_srt), which performs an
in-place sort on a passed in list. Radix sort has a best case time
complexity of O(n log n). This implementation of radix sort is stable, but not
adaptive.

References:

Radix Sort in Python
http://www.geekviewpoint.com/python/sorting/radixsort
by Isai Damier
"""


def radix_srt(un_list):
"""Sort a list in place with radix sort.

args:
un_list: the list of positive integers to be sorted.
"""
radix = 10
maxLen = False
tmp, placement = -1, 1

while not maxLen:
maxLen = True
buckets = [list() for num in range(radix)]

for i in un_list:
tmp = i // placement
buckets[tmp % radix].append(i)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given that floored division and the % operator are quite expensive, can you think of a less CPU intensive way of calculating the needed values here?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Yeah! I haven't played much with bitwise operations yet.

if maxLen and tmp > 0:
maxLen = False

a = 0
for b in range(radix):
buck = buckets[b]
for i in buck:
un_list[a] = i
a += 1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A much less wordy way of doing this same thing:

[i for i in b for b in buckets]

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or using itertools:

[i for i in itertools.chain(*buckets)]

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, neat!


placement *= radix


if __name__ == '__main__':
from random import randint
WORST_CASE = [randint(9000, 10000) for x in range(1, 10001)]
BEST_CASE = [randint(0, 9) for x in range(1, 10001)]

from timeit import Timer

SETUP = """from __main__ import BEST_CASE, WORST_CASE, radix_srt"""

best = Timer('radix_srt({})'.format(BEST_CASE), SETUP).timeit(100)

worst = Timer('radix_srt({})'.format(WORST_CASE), SETUP).timeit(100)

print("""
Best case represented as a list with integers between 0 and 9.
Worst case represented as a list with large integers (here, between
9000 and 9999).
""")
print('Best Case: {}'.format(best))
print('Worst Case: {}'.format(worst))
40 changes: 40 additions & 0 deletions test_radix_sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from random import shuffle
import pytest

from radix_sort import radix_srt


def test_radix_srt():
expected = range(20)
actual = expected[:]
shuffle(actual)
radix_srt(actual)
assert expected == actual


def test_radix_srt_with_duplicates():
expected = [1, 3, 3, 6, 7, 8, 8, 8]
actual = expected[:]
shuffle(actual)
radix_srt(actual)
assert expected == actual


def test_radix_srt_with_zero_items():
expected = []
actual = []
radix_srt(actual)
assert expected == actual


def test_radix_srt_with_one_item():
expected = [1]
actual = [1]
radix_srt(actual)
assert expected == actual


def test_radix_sort_wrong_type():
with pytest.raises(TypeError):
radix_srt(15)