簡體   English   中英

無法跟蹤我的合並排序算法(Python 3)

[英]Trouble tracing my Merge sort algorithm (Python 3)

我在 Python 3 中編寫了一個簡短的合並排序算法。我很難理解它是如何實現正確結果的,因為當我嘗試跟蹤它的邏輯步驟時,我最終得到了一個亂序列表。 注釋代碼如下所示。

我具體指的是代碼的合並部分。 三個“while”循環。

讓我用一個例子來說明什么讓我感到困惑。 我在注釋中解釋了細節。

提前感謝您的時間和幫助。

假設我們要合並兩個 arrays。

left = [2,6]
right = [4,8]

def merge_sort(array):

    if len(array) > 1:

        middle = len(array)//2

        left = array[:middle]
        right = array[middle:]

        merge_sort(left)
        merge_sort(right)

        i = j = k = 0

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

            # i.e. if 2 < 4
            if left[i] < right[j]: 

                # The first index of the array is assigned the value 2
                array[k] = left[i]  

                # i = 1 now
                i += 1

            # The 'else' statement is not executed, because the 'if' statement was.
            else:

                array[k] = right[j]
                j += 1

            # k = 1 now
            k += 1 

        # The 'while' loop below assigns '6' as the value for index 1 of the array and terminates.
        # k = 2 now
        while i < len(left):
       
            array[k] = left[i]
            i += 1
            k += 1

        # The last 'while' loop assigns '4' and '8' to indexes 2 and 3 of the array, respectively.
        while j < len(right):

            array[k] = right[j]
            j += 1
            k += 1

        # The algorithm terminates and from what I can see I should end up with the array of [2,6,4,8].
        # I do not, however. It is sorted in ascending order and I cannot see where I'm making a mistake.

首先,請注意您的措辭,要明確合並排序不會合並不同的 arrays,合並排序巧妙地將單個未排序的數組解構為子數組(在我們的例子中為左右)並將它們單獨排序並將它們合並回單個再次進行最終排序的數組。 換句話說,您將這個 function 傳遞給一個未排序的單個數組,它會返回一個已排序的數組。 如果你需要合並兩個 arrays,你會在調用它之前這樣做。

合並排序

“合並排序是一種遞歸算法,它不斷將列表分成兩半。如果列表為空或有一項,則按定義排序(基本情況)。如果列表有多個項目,我們將列表拆分並遞歸地在兩半上調用合並排序。一旦兩半排序完畢,就會執行稱為合並的基本操作。合並是獲取兩個較小的排序列表並將它們組合成一個單獨的排序新列表的過程。 "

調試/分析代碼

為了幫助理解它的工作原理(和調試),至少注入打印注釋以最好地更詳細地顯示正在發生的事情。 我已經接受了您編寫的內容並添加了打印注釋,並向 function 傳遞了一個字符串,以幫助確定它正在排序的數組(左或右)。 您可以看到拆分排序和合並,因為它通過將數組拆分為大小為一並在此過程中合並排序的子 arrays 等來完成排序...

def merge_sort(array,type):
    print('merge_sort =>' + type)
    if len(array) < 2:
        print('Array < 2 nothing changed')
        return array
    middle = len(array) // 2
    left = array[:middle]
    right = array[middle:]
    print('splitting : ' + str(array))
    merge_sort(left,'left')
    merge_sort(right,'right')
    i = j = k = 0
    print('sorting.. Left/Right:' + str(left) + str(right))
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            print(' - left[i] < right[j] ('+ str(left[i]) + ' < ' + str(right[j]) + ') set array[' + str(k) + '] = ' + str(left[i]) + '')
            array[k] = left[i]
            i += 1
        else:
            print(' - else left[i] >= right[j] ('+ str(left[i]) + ' >= ' + str(right[j]) + ') set array[' + str(k) + '] = ' + str(right[j]) + '')
            array[k] = right[j]
            j += 1
        k += 1
    while i < len(left):
        print(' - WHILE i < len(left), ('+str(i) +' < '+str(len(left))+'), set array[' + str(k) + '] = ' + str(left[i]) + '')
        array[k] = left[i]
        i += 1
        k += 1
    while j < len(right):
        print(' - while j < len(right) ('+str(j) +' < ' + str(len(right)) + '), set array[' + str(k) + '] = ' + str(right[j]) + '')
        array[k] = right[j]
        j += 1
        k += 1
    print("returning.." + str(array))
    return array

arr = [2,6,4,8]
result = merge_sort(arr,'full')
print(result)

其中提供以下output:

merge_sort =>full
splitting : [2, 6, 4, 8]
merge_sort =>left
splitting : [2, 6]
merge_sort =>left
Array < 2 nothing changed
merge_sort =>right
Array < 2 nothing changed
sorting.. Left/Right:[2][6]
 - left[i] < right[j] (2 < 6) set array[0] = 2
 - while j < len(right) (0 < 1), set array[1] = 6
returning..[2, 6]
merge_sort =>right
splitting : [4, 8]
merge_sort =>left
Array < 2 nothing changed
merge_sort =>right
Array < 2 nothing changed
sorting.. Left/Right:[4][8]
 - left[i] < right[j] (4 < 8) set array[0] = 4
 - while j < len(right) (0 < 1), set array[1] = 8
returning..[4, 8]
sorting.. Left/Right:[2, 6][4, 8]
 - left[i] < right[j] (2 < 4) set array[0] = 2
 - else left[i] >= right[j] (6 >= 4) set array[1] = 4
 - left[i] < right[j] (6 < 8) set array[2] = 6
 - while j < len(right) (1 < 2), set array[3] = 8
returning..[2, 4, 6, 8]

這會產生一些東西。 像這樣: 在此處輸入圖像描述

參考: 如何在 python 中合並 arrays? https://runestone.academy/runestone/books/published/pythonds/SortSearch/TheMergeSort.html

在您的注釋中,您似乎過早地退出了第一個while循環,當代碼實際運行 3 次時,您在一次運行后停止。 以下是您將如何關注 wgat 實際發生的情況:

  • 你通過它一次,然后你有k=1i=1j=0
  • 所以你 go 再次通過這個循環(這次是else被執行,並將 4 分配給數組的索引 1,現在k=2i=1j=1
  • 所以你第三次運行循環, if執行,最后是k=3i=2j=1 ,所以你退出第一個while

暫無
暫無

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

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