簡體   English   中英

合並排序混亂中的遞歸調用

[英]Recursive call in merge sort confusion

這是代碼:

def mergeSort(myList):
    if len(myList) > 1:
        mid = len(myList) // 2
        left = myList[:mid]
        right = myList[mid:]

        # Recursive call on each half
        mergeSort(left)
        mergeSort(right)

        # Two iterators for traversing the two halves
        i = 0
        j = 0
        
        # Iterator for the main list
        k = 0
        
        while i < len(left) and j < len(right):
            if left[i] <= right[j]:
              # The value from the left half has been used
              myList[k] = left[i]
              # Move the iterator forward
              i += 1
            else:
                myList[k] = right[j]
                j += 1
            # Move to the next slot
            k += 1

        # For all the remaining values
        while i < len(left):
            myList[k] = left[i]
            i += 1
            k += 1

        while j < len(right):
            myList[k]=right[j]
            j += 1
            k += 1

myList = [2,4,1,5,3]
mergeSort(myList)
print(myList)

我的疑問是調用了 mergeSort(left) 和 mergeSort(right) 函數,但沒有 return 語句,那么列表的順序如何更改,更改后的列表如何返回給函數,沒有 return 語句。Ps :我仍然是初學者,所以請嘗試為我簡化它謝謝

沒有返回語句,那么列表的順序如何改變

在對myList[k]進行賦值的每個實例中,它都會發生變化。 由於這確實是調用者提供給您的函數的列表,因此調用者會注意到對其值的任何更改。

調用者知道該函數是否會為myList本身分配一個新值(就像myList = [] ),但是當它發生變異(使用myList[k] = ... )時,這會改變調用者的列表. 該函數和調用者正在訪問同一個列表。

更改后的列表如何返回

它不會退回。 這就是就地排序所做的:該函數不會創建一個新列表來按排序順序將值復制到其中——在這種情況下,它必須將該列表返回給調用者。 不,通過就地排序,列表本身中的值會四處移動,從而影響調用者擁有的一個列表。

因此,在函數運行完成后,調用者可以檢查列表並查看它現在是否已排序。

混合情況

現在,通過典型的合並排序,會創建其他臨時列表,但它們僅用於留出一些值,但它們確實會移回調用者的列表中,之后這些臨時列表將過時。

例如,這里使用給定列表中值的副本創建了兩個新列表:

left = myList[:mid]
right = myList[mid:]

這些都通過遞歸調用進行了變異(排序):

mergeSort(left)
mergeSort(right)

但隨后該功能的其余部分專用於從(排序)的值復制leftright列表到調用方的名單( myList ),因此,在年底leftright不再需要,而myList進行排序。

暫無
暫無

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

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