我编写了以下合并排序代码:
def merge_sort(self,a):
#console.log(len(a))
if len(a) <= 1:
return a
left = []
right = []
result = []
middle = int(len(a)/2)
print middle
left = a[:middle] #set left equal to the first half of a
right = a[middle:] #set right equal to the second half of a
print left
print right
left = self.merge_sort(left)
right = self.merge_sort(right)
result = self.merge(left, right)
return result
然后合并代码:
def merge(self, left, right):
result = []
while len(left) > 0 or len(right) > 0:
if len(left) > 0 and len(right) > 0:
if left[0] <= right[0]:
result.append(left[0])
left = left.pop(1) #remove the first element from left
elif len(left) > 0:
result.append(left[0])
left = left.pop(1) #remove the first element from left
elif len(right) > 0:
result.append(right[0])
right = right.pop(1) #remove the first element from right
else:
result.append(right[0])
right = right.pop(1)
return result
我发送数组: a = [12,0,232]
我得到以下输出(不同的迭代),并在最后一个输出我得到错误,请帮助我不明白为什么错误是有的,谢谢!:
(1 [12] [0,232]) (1 [0] [232])
追踪(最近一次通话): 合并中的...... \ Sort_Class.py“,第116行 left = left.pop(1)#remove第一个元素从左边开始 IndexError:pop index超出范围
答案 0 :(得分:3)
您的代码存在问题,例如在此选择中它们都存在:
result.append(left[0])
left = left.pop(1)
这应该是:
result.append(left.pop(0))
问题是:
left[0]
是列表的第一个元素left[1]
,因此left.pop(0)
弹出第一个元素,而left.pop(1)
弹出第二个元素< / LI>
left.pop(1)
返回弹出的元素,而不是列表,因为它会改变列表。 left = left.pop(1)
在这里没有多大意义。left[0]
获取第一个元素,然后弹出它left.pop(0)
答案 1 :(得分:0)
我认为.pop()
不符合你的想法。例如,这一行:
left = left.pop(1) #remove the first element from left
不会从left
中删除“第一个”(即第零个)元素。 .pop(1)
是第二个要素:
>>> a = [10,20,30,40]
>>> a.pop(1)
20
>>> a
[10, 30, 40]
此外,如果您设置a = a.pop(1)
,则a
不再是列表,而是数字:
>>> a = [10,20,30,40]
>>> a = a.pop(1)
>>> a
20
也无效。您可以使用del left[0]
或left = left[1:]
或仅result.append(left.pop(0))
替换这些内容,如刚刚发布的答案中所述。 :^)修复显示另一个问题,但是:由于这里的逻辑,你的代码被无限循环捕获:
if len(left) > 0 and len(right) > 0:
if left[0] <= right[0]:
如果left[0] > right[0]
,则没有分支,left
或right
都没有任何问题,而且您被困。如果你调整这个来为这种情况添加一个右分支行为,你的代码似乎可以工作:
>>> import random
>>> def check():
... for length in range(1, 10):
... for trial in range(10000):
... v = [random.randrange(-10, 10) for i in range(length)]
... assert merge_sort(v) == sorted(v)
... return True
...
>>> check()
True