[英]Implementing Merge Sort algorithm
def merge(arr,l,m,h):
lis = []
l1 = arr[l:m]
l2 = arr[m+1:h]
while((len(l1) and len(l2)) is not 0):
if l1[0]<=l2[0]:
x = l1.pop(0)
else:
x = l2.pop(0)
lis.append(x)
return lis
def merge_sort(arr,l,h): generating them
if l<h:
mid = (l+h)//2
merge_sort(arr,l,mid)
merge_sort(arr,mid+1,h)
arr = merge(arr,l,mid,h)
return arr
arr = [9,3,7,5,6,4,8,2]
print(merge_sort(arr,0,7))
谁能告诉我我的方法哪里出错了? 我只得到 [6,4,8] 作为答案。 我试图理解算法并以自己的方式实现逻辑。 请帮忙。
几个问题:
当您认为h
是子列表的最后一个索引时,请意识到在对列表进行切片时,第二个索引是预期范围之后的索引。 所以改变这个:
错误的 | 正确的 |
---|---|
l1 = arr[l:m] |
l1 = arr[l:m+1] |
l2 = arr[m+1:h] |
l2 = arr[m+1:h+1] |
由于merge
返回子列表的结果,因此不应将其分配给arr
。 arr
应该是总列表,所以你应该只替换它的一部分:
arr[l:h+1] = merge(arr,l,mid,h)
由于while
循环要求两个列表都不为空,因此您仍应考虑在循环之后其中一个列表仍不为空的情况:应将其元素添加到合并结果中。 所以将return
语句替换为:
return lis + l1 + l2
不建议将整数与is
或is not
进行比较,您在while
条件下会这样做。 事实上,这个条件可以简化为:
while l1 and l2:
通过这些更改(和正确的缩进),它将起作用。
这种实现效率不高。 pop(0)
的时间复杂度为 O(n)。 使用您在循环期间更新的索引,而不是真正从列表中提取值。
让h
和m
成为它们关闭的范围之后的索引,而不是它们是它们关闭的范围内的最后一个元素的索引,这更像是 Pythonic。 所以如果你 go 那样,那么上面的一些问题将得到不同的解决。
这是使用上述所有注释改编的代码:
def merge(arr, l, m, h):
lis = []
i = l
j = m
while i < m and j < h:
if arr[i] <= arr[j]:
x = arr[i]
i += 1
else:
x = arr[j]
j += 1
lis.append(x)
return lis + arr[i:m] + arr[j:h]
def merge_sort(arr, l, h):
if l < h - 1:
mid = (l + h) // 2
merge_sort(arr, l, mid)
merge_sort(arr, mid, h)
arr[l:h] = merge(arr, l, mid, h)
return arr
arr = [9, 3, 7, 5, 6, 4, 8, 2]
print(merge_sort(arr,0,len(arr)))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.