2016-03-02 68 views
1

我對合並工作排序使用遞歸的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] 

我期望的最後第三行應爲「[1100] R [54 ,91]「之後回來。 這裏有什麼問題?我知道interactivePython.org中有一個代碼,但我想知道我在哪裏犯了邏輯錯誤。誰能幫我?一噸謝謝!

+0

如果'LEN(的Xlist)> 1'是不正確的,功能不執行任何操作,因此它返回無。這是故意的嗎? –

+1

你的代碼的後半部分並沒有真正進行合併排序。附加到'left'不是合併 - 它依靠你的清理代碼*低調地*按照正確的順序排列列表。你已經有效地實現了一個** shell排序**的僞裝合併排序。 –

回答

1

你需要決定你mergesort代碼是否要修改它傳遞的列表到位,還是要返回新列表。代碼的頂部部分被編寫爲就像它將修改列表一樣。下半部分寫成好像它返回一個新列表。他們都需要以相同的方式工作,否則排序不起作用。

如果你想堅持就地修改的方法,代碼的頂部部分是沒問題的,它只是合併leftright在最後你需要修復。而不是合併到left,您需要合併到xlist。我建議在每個列表中使用單獨的索引,而不是像你目前正在做的那樣在left中插入昂貴的代碼。

如果你想返回一個新的列表,你需要改變代碼的頂部。如果您遇到基本情況(len(xlist) < 2),則需要返回xlist未修改。您還需要從遞歸調用保存的返回值,也許left = mergesort(left)right = mergesort(right)。你後來合併代碼可能是好的,但它丟棄大部分歸併排序的性能優勢,由於插入邏輯是O(N**2)

+0

其實我也想修改我的代碼加入「的Xlist =左」恰到好處打印之前」(‘排序’,左,正確,xlist)「並刪除」返回「。這是修改原地方法,但它仍然不起作用。 – Hsiang

+0

'xlist = left'不會修改'xlist'指向的列表,它只是重新綁定名稱。你可以做'xlist [:] = left',但是直接將'left'和'right'的值合併到'xlist'中真的會更好(你當前的合併過程非常低效)。 – Blckknght

+0

謝謝!它現在有效。 xlist = left和xlist [:] = left有什麼區別?另外感謝您的提醒,我目前的合併程序完全沒有效率。 – Hsiang

0

我花了幾分鐘的時間,但我發現它。您在左側&右側正確地重複,但是然後您丟棄結果併合並原始列表。產品糾錯:

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] 
+0

謝謝!但實際上我試圖按照你的建議,它顯示以下錯誤消息(我使用ipython): ..... mergeSort(xlist)中的 12 print(left ,'r',right) ---> 14 while len(right)> 0: 15 left.append(right [0]) 16 right。刪除(右[0]) 類型錯誤:類型NoneType「的對象沒有LEN() – Hsiang