Background
- Non comparison integer sorting by grouping numbers based on individual digits or radix (base)
- Perform iteratively from least significant digit (LSD) to most significant digit (MSD) or recusively from MSD to LSD.
- At each iteration, sorting of target digit is based usually on Counting sort as subroutine.
- Complexity: O(d*n+b)) where b is the base for representing numbers eg 10. d is the number of digits. Close to Linear time if d is constant amount
Counting Sort as subroutine
- Recap on the counting sort. See Counting Sort in Python for more info
- Taking “get_sortkey ” function that generate the keys based on objects characteristics.
- Modified the get_sortkey function to perform radix sort.
import random, math def get_sortkey(n): """ Define the method to retrieve the key """ return n def counting_sort(tlist, k, get_sortkey): """ Counting sort algo with sort in place. Args: tlist: target list to sort k: max value assume known before hand get_sortkey: function to retrieve the key that is apply to elements of tlist to be used in the count list index. map info to index of the count list. Adv: The count (after cum sum) will hold the actual position of the element in sorted order Using the above, """ # Create a count list and using the index to map to the integer in tlist. count_list = [0]*(k) # iterate the tgt_list to put into count list for n in tlist: count_list[get_sortkey(n)] = count_list[get_sortkey(n)] + 1 # Modify count list such that each index of count list is the combined sum of the previous counts # each index indicate the actual position (or sequence) in the output sequence. for i in range(k): if i ==0: count_list[i] = count_list[i] else: count_list[i] += count_list[i-1] output = [None]*len(tlist) for i in range(len(tlist)-1, -1, -1): sortkey = get_sortkey(tlist[i]) output[count_list[sortkey]-1] = tlist[i] count_list[sortkey] -=1 return output
Radix sort with up to 3-digits numbers
- Replace the get_sortkey with the get_sortkey2 which extract the integer based on the digit place and uses the counting sort at each iteration
# radix sort from functools import partial def get_sortkey2(n, digit_place=2): """ Define the method to retrieve the key return the key based on the digit place. Current set base to 10 """ return (n//10**digit_place)%10 ## Create random list for demo counting sort. random.seed(1) tgt_list = [random.randint(20,400) for n in range(10)] print("Unsorted List") print(tgt_list) ## Perform the counting sort. print("\nSorted list using counting sort") output = tgt_list for n in range(3): output = counting_sort(output, 30, partial(get_sortkey2, digit_place=n)) print(output) ## output # Unsorted List # [88, 311, 52, 150, 80, 273, 250, 261, 353, 214] # Sorted list using counting sort # [150, 80, 250, 311, 261, 52, 273, 353, 214, 88] # [311, 214, 150, 250, 52, 353, 261, 273, 80, 88] # [52, 80, 88, 150, 214, 250, 261, 273, 311, 353]
See also:
Resources: