我尝试实现合并排序,这是我的代码:
def mergeSort(array):
result=[]
n=len(array)
if n==1:
result=array
else:
a=round(n/2)
first=mergeSort(array[0:a])
second=mergeSort(array[a:n])
for i in range(len(first)):
for j in range(len(second)):
if first[i]<second[j]:
result.append(first[i])
i=i+1
else:
result.append(second[j])
j=j+1
return result
a=[5,4,1,8,7,6,2,3]
b=mergeSort(a)
print(b)
不幸的是,结果证明是[1]
。我的功能出了什么问题?
答案 0 :(得分:4)
很多事情......
首先,这是一个递归函数,这意味着你不能像在这里一样在函数中创建一个列表:
result=[]
这会在每次递归调用后重置您的列表,从而扭曲您的结果。最简单的方法是更改作为参数传递的列表以合并排序。
你的下一个问题是你在for循环中有一个for循环。这不起作用,因为当第一个for循环迭代first
时,第二个for循环将针对second
的每个增量迭代i
,这不是你想要的。您需要的是比较first
和second
并提取最小值,然后提取下一个最小值,依此类推,直到获得排序列表。
所以你的for循环需要改为:
while i < len(first) and j < len(second):
这导致我在您的代码中遇到最终问题。在满足其中一个条件后,while循环将退出,这意味着i
或j
(一个或另一个)将不会达到len(first)
或len(second)
。换句话说,first
或second
中有一个值是未计入的值。您需要将此未计入值添加到已排序列表中,这意味着您必须在函数末尾实现此最终摘录:
remaining = first if i < j else second
r = i if remaining == first else j
while r < len(remaining):
array[k] = remaining[r]
r = r + 1
k = k + 1
此处r
表示前一个while循环中断的索引值。然后while循环将遍历剩余的剩余值;将它们添加到排序列表的末尾。
现在,合并排序应如下所示:
def mergeSort(array):
if len(array)==1:
return array
else:
a=round(len(array)/2)
first=mergeSort(array[:a])
second=mergeSort(array[a:])
i = 0
j = 0
k = 0
while i < len(first) and j < len(second):
if first[i]<second[j]:
array[k] = first[i]
i=i+1
k=k+1
else:
array[k] = second[j]
j=j+1
k=k+1
remaining = first if i < j else second
r = i if remaining == first else j
while r < len(remaining):
array[k] = remaining[r]
r += 1; k += 1
return array
我尽量不改变您的代码,以便您更容易理解。但是,如果您难以理解我所做的事情,请尝试使用多个打印语句来修改合并排序,以便您可以按照函数的进度查看它出错的位置。