【问题标题】:Recursive function, final print statement递归函数,最终打印语句
【发布时间】:2017-02-11 19:34:58
【问题描述】:

我正在自学 Python,使用如何像计算机科学家一样思考。我正在学习“节点和链表”。 这个递归函数让我很困惑。 需要明确的是,代码工作正常。我在问,底部的最后一行代码(print list,)怎么可能被执行?

我的问题是关于这个递归函数:

def print_backward (list):
    if list == None: return  #shouldn't the code terminate when this is satisfied?
    print_backward(list.next)
    print list, #seems like the function would terminate before this line 
                #ever gets called

谁能解释一下,最后一行print head, 什么时候被执行?阅读这段代码,我会认为我们在评估每个节点之后循环回到函数的顶部,然后当我们到达第三个也是最后一个节点时,终止语句if list == None: return将被满足,然后代码将退出循环,永远不会到达最底部的打印语句。显然这并没有发生,因为正在调用 print 语句。

我之所以问,是因为如果我不了解代码的工作原理,我觉得我并没有真正在学习!如果有人可以解释代码如何到达最终的打印语句(并且它正在到达那里),我将非常感激。我希望我问这个问题没有违反规则。谢谢!

顺便说一句,我正在打印一个链接列表,货物是 [1,2,3]。向后打印,所以 [3,2,1] 下面是更多上下文的代码。


class Node:
    def __init__(self, cargo = None, next = None):
        self.cargo = cargo
        self.next = next

    def __str__(self):
        return str(self.cargo)

def print_list(node):
    while node:
        print node,
        node = node.next
    print


def print_backward (list):
    if list == None: return
    print_backward(list.next)
    print list,

node1 = Node(1)
node2 = Node(2)
node3 = Node(3)

node1.next = node2
node2.next = node3
node3.next = None

print_backward(node1)

输出是:

==== RESTART: /Users/Desktop/Programming Career/Untitled.py ====

3 2 1

【问题讨论】:

  • 你混淆了一个空列表[]和一个None

标签: python linked-list nodes tail-recursion


【解决方案1】:

让我们逐个节点解析代码在做什么

  1. print_backwardnode1 调用
  2. node1 == None 没有吗?不,所以我们继续
  3. 我们分配head = node1
  4. 我们分配tail = node1.nexttail = node2 相同
  5. 我们调用print_backward(tail)print_backward(node2) 相同
    1. print_backwardnode2 调用
    2. node2 == None 没有吗?不,所以我们继续
    3. 我们分配head = node2
    4. 我们分配tail = node2.nexttail = node3 相同
    5. 我们调用print_backward(tail)print_backward(node3) 相同
      1. print_backwardnode3 调用
      2. node3 == None 没有吗?不,所以我们继续
      3. 我们分配head = node3
      4. 我们分配tail = node3.nexttail = None 相同
      5. 我们调用print_backward(tail)print_backward(None) 相同
        1. print_backwardNone 调用
        2. None == None 没有吗?是的,所以我们返回
      6. print head, 被调用,与print node3, 相同(打印“3”)
    6. print head, 被调用,与print node2, 相同(打印“2”)
  6. print head, 被调用,与print node1, 相同(打印“1”)

总输出为“3 2 1”!

【讨论】:

  • 这是评估递归函数的一种非常好的方法。谢谢你的详细解释!!!!
【解决方案2】:

递归并不意味着跳到函数的顶部;这意味着在一个函数调用相同的函数。

我认为一个更简单的例子让它更明显:

def count(number):
    if number <= 0: return
    count(number-1)
    print(number)

当我们调用count(3) 时,该函数将打印数字 1 到 3。为什么?因为这就是发生的事情:

  1. count(3) 被调用。
  2. number 是 3,不小于或等于 0,所以我们不return
  3. 我们致电count(3-1):
    1. count(2) 被调用。
    2. number 是 2,不小于或等于 0,所以我们不return
    3. 我们致电count(2-1)
      1. count(1) 被调用。
      2. number 是 1,不小于或等于 0,所以我们不 return
      3. 我们致电count(1-1):
        1. count(0) 被调用。
        2. number是0,也就是0,所以我们return上一层。
      4. 我们print 1.
    4. 我们print 2.
  4. 我们print 3.

【讨论】:

  • 好吧,我明白了——把它想象成“跳到顶端”,我自己都搞糊涂了。当一个函数调用自己时,它会在它所在的地方递归,直到遇到终止语句,然后它会下降到下一行,在这种情况下是 print 语句。谢谢你的详细解释!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 2019-09-09
  • 2015-05-18
  • 2013-05-24
  • 2023-02-18
  • 1970-01-01
  • 2017-06-16
相关资源
最近更新 更多