递归归并排序的功能实现?

问题描述

尝试在 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,mid)          # Recursively split the left half
        merge_sort (arr,mid+1,high)       # Recursively split the right half
        
        return merge(arr,mid,high)   # merge halves together

def merge (arr,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,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(),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 来解决。但是,这超出了范围。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...