问题描述
尝试在 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 来解决。但是,这超出了范围。