我试图在不使用切片的情况下编写一个快速排序实现但是我遇到运行中途的问题 - 想知道是否有人能告诉我我哪里出错了
我添加了一些打印声明(已注释掉),因此您可以看到每个阶段之前和之后发生的事情:
def mergesort(arr, l, r):
#print('start: ', arr[l:r])
if len(arr[l:r]) <=1:
return arr[l:r]
mid = l + (r-l) // 2
left = mergesort(arr, l, mid)
right = mergesort(arr, mid, r)
l_idx = l
r_idx = mid
final = []
while l_idx < mid and r_idx < r:
if arr[l_idx] <= arr[r_idx]:
final.append(arr[l_idx])
l_idx+=1
else:
final.append(arr[r_idx])
r_idx+=1
for val in arr[l_idx:mid]:
final.append(val)
for val in arr[r_idx:r]:
final.append(val)
#print('final: ', final[l:r])
#print()
#print()
return final
print(merge([0, 9, 3, 7, 4, 2, 6, 1], 0, 8))
我得到的价值表明,左边有效,但右边没有。这很好奇,因为它似乎适用于左侧的右侧......
标准输出是:
start: [0, 9, 3, 7, 4, 2, 6, 1]
start: [0, 9, 3, 7]
start: [0, 9]
start: [0]
start: [9]
final: [0, 9]
start: [3, 7]
start: [3]
start: [7]
final: []
final: [0, 3, 7, 9]
start: [4, 2, 6, 1]
start: [4, 2]
start: [4]
start: [2]
final: []
start: [6, 1]
start: [6]
start: [1]
final: []
final: []
final: [0, 4, 2, 6, 1, 9, 3, 7]
答案 0 :(得分:0)
主要问题是你永远不会使用从递归调用返回的left
和right
列表,但是你需要这些,因为arr
没有改变一个位那些电话。当你纠正这个时,你也应该知道这个结果列表将从索引0开始,与你通过递归调用传递的l
的值无关。所以这意味着实际的合并循环需要从索引0开始,而不是l
。
以下是递归调用后应该具有的代码:
# concatenate the left and right results into arr
arr = left + right
# realign the indexes with the new arr
mid -= l
r -= l
l_idx = 0
r_idx = mid
进行此更改it will work。
注意:你说你想要在没有切片的情况下这样做,但请注意你仍然会切片:每当你使用:
表示法时,你就会切片。