2013-02-08 128 views
1

我的代碼有什麼問題?它僅打印vect值的一部分。似乎while循環在某個時候斷了。我不明白爲什麼。合併排序問題 - Python

def print_list(vect): 
    for i in range(0, len(vect)): 
     print(vect[i]) 

def merge_sort(vect): 
    left = [] 
    right = []  
    result = [] 

    for i in range(0, int(len(vect)/2)): 
     left.append(vect[i]) 
    for i in range(int(len(vect)/2), len(vect)): 
     right.append(vect[i]) 

    left.sort() 
    right.sort() 
    i = 0 
    j = 0 

    while i < len(left) and j < len(right): 
     if left[i] <= right[j]: 
      result.append(left[i]) 
      i += 1 
     else: 
      result.append(right[j]) 
      j += 1 

    print(len(result)) 
    return result 

vect = [3, 1, 5, 7, 10, 2, 0] 

vect = merge_sort(vect) 
+1

我不明白你爲什麼要調用'left.sort()'和'right.sort()'。這對列表的每一半使用Python的內部排序功能,這使得mergesort的實現完全沒有意義。 – 2013-02-08 17:46:53

回答

5

那麼,你的錯誤是,while循環後

while i < len(left) and j < len(right): 
    ... 

可能(而且很可能會),要麼i < len(left)j < len(right),所以你需要適當部分的後綴追加到答案。這很容易與

result += left[i:] 
result += right[j:] 

說明做:

想象的合併過程:你有i和j在0在啓動,並在每個步驟中,您將它們移動的一個前進。當你停下來?當他們中的一個到達最後。假設我已經達到了目的。因此,您在結果中添加了整個左側部分,但j和len之間仍有一些元素(右側),因此您必須將它們添加到答案中。

Offtop

要實現歸併排序,所以請

left = merge_sort(left) 
right = merge_sort(right) 

代替

left.sort() 
right.sort() 

注意:您有下列檢查添加到您的代碼在合併函數的開頭,以避免無限遞歸:

if len(vect) == 1: 
    return vect 

而且在你print_list功能,您可以只使用

print vect 

或至少

for x in vect 
print x 
+0

有我 2013-02-08 17:33:14

+0

@ user1392136:是的,所以它會在我> = len(左)或j> = len(右)時破壞。其他指數可能仍然較低。 – 2013-02-08 17:34:50

+0

所以答案是,我需要OR而不是和那裏..如果我嘗試與OR,我收到索引超出範圍... – 2013-02-08 17:41:50

3

while循環,一旦退出的向左或向右耗盡。這使未用完列表中剩下的所有元素都未被合併。

你的代碼改成這樣:

def print_list(vect): 
    for i in range(0, len(vect)): 
     print(vect[i]) 

def merge_sort(vect): 
    left = [] 
    right = [] 

    result = [] 
    for i in range(0, int(len(vect)/2)): 
     left.append(vect[i]) 
    for i in range(int(len(vect)/2), len(vect)): 
     right.append(vect[i]) 

    left.sort(); 
    right.sort(); 
    i = 0 
    j = 0 

    while i < len(left) and j < len(right): 
     if left[i] <= right[j]: 
      result.append(left[i]) 
      i += 1 
     else: 
      result.append(right[j]) 
      j += 1 

    if i < len(left): 
     result.extend(left[i:]) 
    else: 
     result.extend(right[j:]) 

    print(len(result)) 
    return result 

vect = [3, 1, 5, 7, 10, 2, 0] 

vect = merge_sort(vect) 
print vect 

如果您使用的排序方法對左,右,我有點困惑,爲什麼你不只是使用它的名單上整個。但我想你有你的理由。 :)

編輯:我把整個代碼塊,讓你可以看到它。當我運行這個時,它打印[0,1,2,3,5,7,10],這是正確的。

+1

我不明白爲什麼我需要在while的末尾加上這個。然而,它不起作用... – 2013-02-08 17:33:48

+0

我調整了答案是更加明確一點。也許它現在適合你。 – 2013-02-08 17:38:51

+0

我不明白爲什麼以及我需要擴展到什麼程度才能使它工作...您能否用一些細節來說明您使用新代碼行的方式? – 2013-02-08 17:43:10