您好我是新手编程所以在学校我们正在学习递归和二叉树。但对我来说,递归是真正让我的思绪消失的东西。
所以我试图在二叉树上尝试输出预订格式
的递归函数def preorder(self, preorder_list):
""" (BinaryTree) -> list
Return a list of the items in this tree using a *preorder* traversal.
"""
if self.root is not EmptyValue:
if self.left and self.right != None:
preorder_list.append(self.left.preorder(preorder_list))
preorder_list.append(self.right.preorder(preorder_list))
def helper_preorder(self):
preorder_list = []
self.preorder(preorder_list)
return preorder_list
当我运行此代码时,我得到的输出是:
例如;
[None, None, None, None]
现在我怀疑这是我的递归推理的一个问题。所以我想知道我的递归推理有什么问题,以及如何在递归中改善自己。
感谢您的时间。
答案 0 :(得分:2)
您的问题是,您永远不会从preorder
返回任何内容,而Python会隐式返回None
。因此,您将函数的返回值附加到列表中,但该值为None
。你的函数应该是这样的(在伪代码中,不是有效的Python) 1 :
preorder(node, list):
if node is Empty:
return list
else:
new_list.append(node.data)
preorder(node.left, new_list);
preorder(node.right, new_list);
return list
请注意,我正在复制return语句,因此您可以优化它,但我这样设置它是因为如果您将其视为基本案例或递归调用,它最容易理解递归。 / p>
要理解递归 2 ,请考虑将难题解决为更小,更容易的问题。我将举一个简单的例子,一个经典的递归示例:factorial(n)
。
什么是factorial(n)
?这是一个非常难以回答的问题,所以让我们找一些更简单的东西。
从数学课上我们知道n! = n*(n-1)*(n-2)*...*(2)*(1)
,所以让我们从那里开始。我们可以立即看到n! = n * (n-1)!
。这有帮助;现在我们可以写一个我们的阶乘函数的启动器:
factorial(n):
return n * factorial(n-1)
但它还没有完成;如果我们运行它,它将永远不会停止 3 。因此,我们需要所谓的基本案例:递归的停止点,问题现在非常简单,我们知道答案。
幸运的是,我们有一个自然的基础案例:1! = 1
,根据定义,这是真的。所以我们将它添加到我们的函数中:
factorial(n):
if n == 1: return 1
else return n * factorial(n)
为了清楚说明这是如何运作的,让我们对一些小事进行追踪,比如说n=4
。
所以我们打电话给factorial(4)
。显然是4 != 1
,所以factorial(4) = 4*factorial(3)
。现在我们重复这个过程,这是关于递归的美妙之处:将相同的算法应用于原始问题的较小子集,并从这些部分构建解决方案。
我们的跟踪看起来像这样:
factorial(4) = 4*factorial(3)
factorial(4) = 4*3*factorial(2)
factorial(4) = 4*3*2*factorial(1)
现在,我们知道factorial(1)
是:它只是1,我们的基本情况。最后我们有了
factorial(4) = 4*3*2*1
factorial(4) = 24
1 这只是一种可能的方式;还有其他人,但这就是我当场提出的问题 2 你必须先了解递归(对不起;我无法抗拒) 3 在现实世界中,它最终会停止:因为每个递归调用都使用一些内存(为了跟踪函数参数和局部变量等),无限递归的代码最终将超过分配的内存对它,并将崩溃。这是堆栈溢出错误的最常见原因之一