我正在尝试在python中实现LSD基数排序,但是我的代码使用了4个循环,有没有办法可以在三个或更少的时间内完成它?
以下是4个循环:
第一个循环遍历输入列表,将其转换为所需的基数,并将每个数字更改为反向列表,如下所示:
123 --> [3,2,1]
第二个循环遍历新创建的列表,通过添加0使它们具有相同的长度,在输入列表中添加指向相应元素的指针,然后反转列表。就像这样:
input: [1234, 56, 7]
After first loop: [[4, 3, 2, 1], [6, 5], [7]]
After the second loop: [[0, 1, 2, 3, 4], [1, 0, 0, 5, 6], [2, 0, 0, 0, 7]]
使用计数排序的LSD顺序的第三个循环排序元素,代码如下。
第四个循环使用指针将每个东西放在一个带有排序顺序的新列表中。
以下是基数排序的代码:
def radix_sort(collection, radix):
new_collect = []
max_len = 0
#loop through collection, convert them to desired form and put in new_collect
for i in collection:
num = []
while i >= radix:
remain = i % radix
num.append(remain)
i = i // radix
num.append(i)
new_collect.append(num)
if len(num) > max_len:
max_len = len(num)
#loop through new_collect, extend the each item to same length
for i in range(0, len(new_collect)):
space = max_len - len(new_collect[i])
patch = [0 for j in range(space)]
new_collect[i].extend(patch)
#add a pointer to the corresponding element in collection
new_collect[i].append(i)
new_collect[i].reverse()
#sort by digit with counting_sort
for i in range(-1, -1 - max_len, -1):
new_collect = counting_sort(new_collect, radix - 1, i)
#create a new list with same length as collection
return_list = list(range(len(collection)))
#put elements in collection to return_list, using the pointer in new_collect
for i in range(0, len(collection)):
return_list[i] = collection[new_collect[i][0]]
return return_list
以下是计算排序的代码:
def counting_sort(collection, d_range, digit = -1):
d_range += 1
B = list(range(len(collection) + 1))
C = list(range(d_range))
for i in range(d_range):
C[i] = 0
for j in collection:
#C[j] = |{key = j}|
C[j[digit]] += 1
for i in range(1, d_range):
#C[i] = |{key <= i}|
C[i] = C[i] + C[i - 1]
for i in range(len(collection) - 1, -1, -1):
B[C[collection[i][digit]]] = collection[i]
C[collection[i][digit]] -= 1
return B[1:]