[英]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.