簡體   English   中英

遞歸合並排序的功能實現?

[英]Functional implementation of recursive merge sort?

嘗試在 Python 中實現功能遞歸合並排序已經有好幾天了。 除此之外,我希望能夠打印出排序算法的每一步。 有沒有辦法讓這個 Python 代碼以功能范式方式運行? 這是我目前所擁有的......

def merge_sort(arr, low, high):

    #  If low is less than high, proceed. Else, array is sorted
    if low < high:

        mid = (low + high) // 2             # Get the midpoint

        merge_sort (arr, low, mid)          # Recursively split the left half
        merge_sort (arr, mid+1, high)       # Recursively split the right half
        
        return merge(arr, low, mid, high)   # merge halves together

def merge (arr, low, mid, high):
    temp = []

    # Copy all the values into a temporary array for displaying
    for index, elem in enumerate(arr): 
        temp.append(elem)

    left_p, right_p, i = low, mid+1, low

    # While left and right pointer still have elements to read
    while left_p <= mid and right_p <= high:
        if temp[left_p] <= temp[right_p]:   # If the left value is less than the right value. Shift left pointer by 1 unit to the right
            arr[i] = temp[left_p]
            left_p += 1
        else:                               # Else, place the right value into target array. Shift right pointer by 1 unit to the right
            arr[i] = temp[right_p]
            right_p += 1

        i += 1                              # Increment target array pointer

    # Copy the rest of the left side of the array into the target array
    while left_p <= mid:
        arr[i] = temp[left_p]
        i += 1
        left_p += 1

    print(*arr) # Display the current form of the array

    return arr

def main():
    # Get input from user
    arr = [int(input()) for x in range(int(input("Input the number of elements: ")))]

    print("Sorting...")
    sorted_arr = merge_sort(arr.copy(), 0, len(arr)-1)      
    print("\nSorted Array")
    print(*sorted_arr)

if __name__ == "__main__":
    main()

任何幫助,將不勝感激。 謝謝你。

在純函數式歸並排序中,我們不想改變任何值。

我們可以定義一個零變異的遞歸版本,如下所示:

def merge(a1, a2):
  if len(a1) == 0:
    return a2
  if len(a2) == 0:
    return a1
  if a1[0] <= a2[0]:
    rec = merge(a1[1:], a2)
    return [a1[0]] + rec
  rec = merge(a1, a2[1:])
  return [a2[0]] + rec

def merge_sort(arr):
  if len(arr) <= 1:
    return arr
  halfway = len(arr) // 2
  left = merge_sort(arr[:halfway])
  right = merge_sort(arr[halfway:])
  return merge(left, right)

您可以將print(arr)添加到merge_sort的頂部以逐步打印,但技術上的副作用會使其不純(盡管在這種情況下仍然是引用透明的)。 但是,在 python 中,您無法使用 monad 從純計算中分離出副作用,因此如果您想真正避免這種打印,則必須返回層,並在最后打印它們:)

還有,這個版本在技術上做了很多副本列表,所以比較慢。 這可以通過使用鏈表和 consing / unconsing 來解決。 但是,這超出了 scope 的范圍。

暫無
暫無

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

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