关于python:合并排序函数的递归令人困惑

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_堆栈