簡體   English   中英

使用Python進行合並排序的錯誤

[英]a bug of merge sort using Python

我正在使用遞歸Python進行合並排序。 我找不到我犯錯的地方,總是得到錯誤的答案。 代碼如下:

def mergeSort(xlist):
    print ('Splitting',xlist, len(xlist))
    if len(xlist)>1:
       midpoint = len(xlist) // 2
       left  = xlist[:midpoint]
       right = xlist[midpoint:]
       print ('----------------------------')
       mergeSort(left)
       mergeSort(right)

       print (left, 'r', right)

       while len(right) >0:
          left.append(right[0])
          right.remove(right[0])
          slot= len(left)-1
          while slot >0:
              if left[slot] < left[slot-1]: left[slot], left[slot-1] = left[slot-1], left[slot]
              slot -= 1

       print ('sorted',left, right,xlist)
       return left

print('A',mergeSort([100,1,91,54])) 

合並時,輸出還會以錯誤的方式顯示,例如:

 Splitting [100, 1, 91, 54] 
 ---------------------------- 
 Splitting [100, 1] 2
 ---------------------------- 
 Splitting [100] 1 
 Splitting [1] 1 
 [100] r [1] 
 sorted [1, 100] [] [100, 1]
 Splitting [91, 54] 2
 ---------------------------- 
 Splitting [91] 1 
 Splitting [54] 1 
 [91] r [54] 
 sorted [54, 91] [] [91, 54]
 [100, 1] r [91, 54] 
 sorted [1, 54, 100, 91] [] [100, 1, 91, 54]
 A [1, 54, 100, 91]

我希望返回后的最后第三行應為“ [[1,100] r [54,91]”。 怎么了 我知道InteractivePython.org中有一個代碼,但是我想了解我在哪里犯了邏輯錯誤。 誰能幫我? 非常感謝!

您需要確定您的mergesort代碼是要修改它在原處傳遞的列表,還是要返回一個新列表。 編寫代碼的頂部就像編寫代碼一樣會修改列表。 下半部分寫成好像返回了一個新列表。 他們都需要以相同的方式工作,否則排序將無法工作。

如果你想堅持與修改就地方法,代碼的頂部是好的,它是剛剛合並leftright的,你需要修復了盡頭。 您需要合並到xlist ,而不是合並到left 我建議對三個列表中的每個列表使用單獨的索引,而不是像您當前正在向left那樣進行昂貴的插入操作。

如果要返回新列表,則需要更改代碼的頂部。 如果遇到基本情況( len(xlist) < 2 ),則需要返回未修改的xlist 您還需要保存遞歸調用的返回值,也許使用left = mergesort(left)right = mergesort(right) 盡管插入邏輯為O(N**2) ,但您放棄了合並排序的大部分性能優勢,但您以后的合並代碼可能沒問題。

我花了幾分鍾,但我找到了。 您可以正確地左右兩邊重復,但隨后丟棄結果並合並原始列表。 更正:

    print ('----------------------------')
    left  = mergeSort(left)
    right = mergeSort(right)

我希望您現在可以看到效果。


這是產生上面輸出的工作代碼:

def mergeSort(xlist):
    print 'Splitting', xlist, len(xlist)
    if len(xlist) <= 1:
        return xlist
    else:
        midpoint = len(xlist) // 2
        left  = xlist[:midpoint]
        right = xlist[midpoint:]
        print ('----------------------------')
        left  = mergeSort(left)
        right = mergeSort(right)

        print left, 'r', right

        # print "merge", left, right
        while len(right) > 0:
            left.append(right[0])
            right.remove(right[0])
            slot = len(left) - 1
            while slot > 0:
                if left[slot] < left[slot-1]:
                    left[slot], left[slot-1] = left[slot-1], left[slot]
                # print "switched", left
                slot -= 1

        print 'sorted', left, right, xlist
        return left

print 'A',mergeSort([100,1,91,54])

輸出:

A Splitting [100, 1, 91, 54] 4
----------------------------
Splitting [100, 1] 2
----------------------------
Splitting [100] 1
Splitting [1] 1
[100] r [1]
sorted [1, 100] [] [100, 1]
Splitting [91, 54] 2
----------------------------
Splitting [91] 1
Splitting [54] 1
[91] r [54]
sorted [54, 91] [] [91, 54]
[1, 100] r [54, 91]
sorted [1, 54, 91, 100] [] [100, 1, 91, 54]
[1, 54, 91, 100]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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