簡體   English   中英

實現歸並排序算法

[英]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
  • 不建議將整數與isis not進行比較,您在while條件下會這樣做。 事實上,這個條件可以簡化為:

     while l1 and l2:

通過這些更改(和正確的縮進),它將起作用。

補充說明:

這種實現效率不高。 pop(0)的時間復雜度為 O(n)。 使用您在循環期間更新的索引,而不是真正從列表中提取值。

hm成為它們關閉的范圍之后的索引,而不是它們是它們關閉的范圍內的最后一個元素的索引,這更像是 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM