4

I'm trying to implement Radix sort in python.

My current program is not working correctly in that a list like [41,51,2,3,123] will be sorted correctly to [2,3,41,51,123], but something like [52,41,51,42,23] will become [23,41,42,52,51] (52 and 51 are in the wrong place).

I think I know why this is happening, because when I compare the digits in the tens place, I don't compare units as well (same for higher powers of 10).

How do I fix this issue so that my program runs in the fastest way possible? Thanks!

def radixsort(aList):
    BASEMOD = 10
    terminateLoop = False
    temp = 0
    power = 0
    newList = []
    while not terminateLoop:
        terminateLoop = True
        tempnums = [[] for x in range(BASEMOD)]

        for x in aList:
            temp = int(x / (BASEMOD ** power))
            tempnums[temp % BASEMOD].append(x)
            if terminateLoop:
                terminateLoop = False


        for y in tempnums:
            for x in range(len(y)):
                if int(y[x] / (BASEMOD ** (power+1))) == 0:
                     newList.append(y[x])
                     aList.remove(y[x])



        power += 1

    return newList

print(radixsort([1,4,1,5,5,6,12,52,1,5,51,2,21,415,12,51,2,51,2]))
ytpillai
  • 3,194
  • 25
  • 43

2 Answers2

2

Currently, your sort does nothing to reorder values based on anything but their highest digit. You get 41 and 42 right only by chance (since they are in the correct relative order in the initial list).

You should be always build a new list based on each cycle of the sort.

def radix_sort(nums, base=10):
    result_list = []
    power = 0
    while nums:
        bins = [[] for _ in range(base)]
        for x in nums:
            bins[x // base**power % base].append(x)
        nums = []
        for bin in bins:
            for x in bin:
                if x < base**(power+1):
                    result_list.append(x)
                else:
                    nums.append(x)
         power += 1
     return result_list

Note that radix sort is not necessarily faster than a comparison-based sort. It only has a lower complexity if the number of items to be sorted is larger than the range of the item's values. Its complexity is O(len(nums) * log(max(nums))) rather than O(len(nums) * log(len(nums))).

Blckknght
  • 85,872
  • 10
  • 104
  • 150
1

Radix sort sorts the elements by first grouping the individual digits of the same place value. [2,3,41,51,123] first we group them based on first digits.

[[],[41,51],[2],[3,123],[],[],[],[],[],[]]

Then, sort the elements according to their increasing/decreasing order. new array will be

[41,51,2,3,123]

then we will be sorting based on tenth digit. in this case [2,3]=[02,03]

[[2,3],[],[123],[],[41],[51],[],[],[],[]]

now new array will be

    [2,3,123,41,51] 

lastly based on 100th digits. this time [2,3,41,51]=[002,003,041,051]

  [[2,3,41,51],[123],[],[],[],[],[],[],[],[]]

finally we end up having [2,3,41,51,123]

def radixsort(A):
    if not isinstance(A,list):
        raise TypeError('')
    n=len(A)
    maxelement=max(A)
    digits=len(str(maxelement)) # how many digits in the maxelement
    l=[]
    bins=[l]*10 # [[],[],.........[]] 10 bins
    for i in range(digits):
        for j in range(n): #withing this we traverse unsorted array
            e=int((A[j]/pow(10,i))%10)
            if len(bins[e])>0:
                bins[e].append(A[j]) #adds item to the end
            else:
                bins[e]=[A[j]]
        k=0 # used for the index of resorted arrayA
        for x in range(10):#we traverse the bins and sort the array 
            if len(bins[x])>0:
                for y in range(len(bins[x])):
                    A[k]=bins[x].pop(0) #remove element from the beginning
                    k=k+1
            
Yilmaz
  • 4,262
  • 6
  • 24
  • 52