Recursion on a merge sort function is confusing
我了解递归的基本原理,在处理简单的事情时,比如计算一个数的阶乘,这是递归最基本的用法,一点也不令人困惑。然而,当您开始在更复杂的环境中使用递归时,我开始感到非常困惑。
在我的例子中,我想创建一个函数,它使用"合并排序"的方式,使用递归对列表中的项目进行排序。所以我开始工作,这是我第一次尝试时想到的(实际上我不需要修正一些打字错误):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | def merge_sort(ls): size = len(ls) if size <= 1: return ls left = merge_sort(ls[:size/2]) right = merge_sort(ls[size/2:]) return merge(left, right) def merge(left, right): ls = [] ln1 = len(left) ln2 = len(right) length = ln1 + ln2 while length > 0: if not left: ls.append(right.pop(0)) length -= 1 elif not right: ls.append(left.pop(0)) length -= 1 else: if left[0] < right[0]: ls.append(left.pop(0)) length -= 1 elif right[0] < left[0]: ls.append(right.pop(0)) length -= 1 return ls print merge_sort([8,5,4,6,1]) |
我单击了运行,它运行起来了,但我不明白为什么运行起来了。是的,我创建了一段代码,它执行了预期的操作,但我不明白为什么。
所以"合并排序"将列表分成两部分,直到有一个简单的列表包含一个项目。它使用递归来完成这项工作,当我们得到一个简单的列表和一个项目时,它会将它分配给一个新的列表,这个列表是左列表还是右列表。然后,我在"merge"函数中使用这两个新列表对它们进行排序,并以正确的方式将它们合并在一起。到目前为止还不错,但是当我点击"Execute"时,我所期望的是代码在前2个项目处停止,并打印一个包含2个排序项目的小列表。但是"合并排序"仍在继续。即使我认为应该在执行后结束:
1 | return merge(left, right) |
这是我的问题。为什么它会返回到"合并排序"的开头,以及它如何保存旧值而不破坏"合并"生成的新排序的"小列表"?我希望我的问题对你有意义。
谢谢你们的帮助!
答案很广泛。要完全理解这一点,您需要了解stackbuild如何使用递归,以及所述build中的指针如何工作。
这是递归调用的,因为需要通过将列表分成两半进行分解,直到它处于尽可能最小的单位(1或0的剩余部分),完成后,堆栈构建将使用其预定义的指针来跟踪所有以前的调用实例。
这是一个深入的编程语言概念。
有关堆栈堆积和回调的详细信息,请参阅此处。https://en.wikipedia.org/wiki/call_堆栈