我正在努力理解和实现合并排序。我在这个问题上遇到了一堵砖墙,似乎无法获得有效的实施方案。我当前的实现命中了“列表索引超出范围”错误。这是我的代码:
def merge_sort(list_a):
mid = len(list_a) // 2
print('Mid is ', mid)
while len(list_a) > 1:
left = list_a[:mid]
print('Left is now ', left)
right = list_a[mid:]
print('Right is now ', right)
merge_sort(left)
merge_sort(right)
merge(list_a, left, right)
def merge(comb_list, list_a, list_b):
print('Starting the merge.')
a1, b1, c1 = 0, 0, 0
na, nb, nc = len(list_a), len(list_b), len(comb_list)
while a1 < na and b1 < nb:
if list_a[a1] < list_b[b1]:
print('Adding from A')
comb_list[c1] = list_a[a1]
a1 += 1
else:
print('Adding from B')
comb_list[c1] = list_b[b1]
b1 += 1
c1 += 1
while list_a:
comb_list[c1] = list_a[a1]
c1 += 1
a1 += 1
while list_b:
comb_list[c1] = list_b[b1]
c1 += 1
b1 += 1
if __name__ == '__main__':
list_a = [54,26,93,17,77,31,44,55,20]
merge_sort(list_a)
答案 0 :(得分:1)
我对您的脚本进行了三次更改以使其正常工作。正如sshdup所指出的那样while list_a
将始终评估为true,因为您不会删除循环内的任何元素。因此,我已将while list_a:
更改为len(list_a)>a1
,将while list_b:
更改为len(list_b)>b1
。我还根据pseudo code向return merge(list_a, left, right)
方法添加了merge_sort
。添加return
语句后,while
中的merge_sort
也可以替换为if
语句。我已经在一个随机的整数数组上对它进行了测试,但它似乎正常工作,但是,像往常一样,你应该测试你的边缘情况,以确保它按预期工作。
def merge_sort(list_a):
mid = len(list_a) // 2
print('Mid is ', mid)
if len(list_a) > 1:
left = list_a[:mid]
print('Left is now ', left)
right = list_a[mid:]
print('Right is now ', right)
merge_sort(left)
merge_sort(right)
return merge(list_a, left, right)
def merge(comb_list, list_a, list_b):
print('Starting the merge.')
a1, b1, c1 = 0, 0, 0
na, nb, nc = len(list_a), len(list_b), len(comb_list)
while a1 < na and b1 < nb:
if list_a[a1] < list_b[b1]:
print('Adding from A')
comb_list[c1] = list_a[a1]
a1 += 1
else:
print('Adding from B')
comb_list[c1] = list_b[b1]
b1 += 1
c1 += 1
while len(list_a)>a1:
comb_list[c1] = list_a[a1]
del list_a[a1]
c1 += 1
a1 += 1
while len(list_b)>b1:
comb_list[c1] = list_b[b1]
c1 += 1
b1 += 1
if __name__ == '__main__':
list_a = [54,26,93,17,77,31,44,55,20]
merge_sort(list_a)
print list_a
答案 1 :(得分:1)
要使代码有效,您必须进行2次调整:
工作代码:
def merge_sort(list_a):
mid = len(list_a) // 2
print('Mid is ', mid)
#Use if statement instead
if len(list_a) > 1:
left = list_a[:mid]
print('Left is now ', left)
right = list_a[mid:]
print('Right is now ', right)
merge_sort(left)
merge_sort(right)
merge(list_a, left, right)
#Print the result
print(list_a)
#Or return it directly:
#return list_a
def merge(comb_list, list_a, list_b):
print('Starting the merge.')
a1, b1, c1 = 0, 0, 0
na, nb, nc = len(list_a), len(list_b), len(comb_list)
while a1 < na and b1 < nb:
if list_a[a1] < list_b[b1]:
print('Adding from A')
comb_list[c1] = list_a[a1]
a1 += 1
else:
print('Adding from B')
comb_list[c1] = list_b[b1]
b1 += 1
c1 += 1
#Change while loop:
while a1 < na:
comb_list[c1] = list_a[a1]
c1 += 1
a1 += 1
#Change while loop:
while b1 < nb:
comb_list[c1] = list_b[b1]
c1 += 1
b1 += 1
if __name__ == '__main__':
list_a = [54,26,93,17,77,31,44,55,20]
merge_sort(list_a)
您可能希望直接返回结果,只需添加
即可return list_a
在merge_sort()函数的末尾。使用该方法,您可以使用main方法中的print(merge_sort(list_a))直接打印结果。