理解二叉树的递归

时间:2014-10-25 19:32:26

标签: python recursion

您好我是新手编程所以在学校我们正在学习递归和二叉树。但对我来说,递归是真正让我的思绪消失的东西。

所以我试图在二叉树上尝试输出预订格式

的递归函数
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]

现在我怀疑这是我的递归推理的一个问题。所以我想知道我的递归推理有什么问题,以及如何在递归中改善自己。

感谢您的时间。

1 个答案:

答案 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 在现实世界中,它最终会停止:因为每个递归调用都使用一些内存(为了跟踪函数参数和局部变量等),无限递归的代码最终将超过分配的内存对它,并将崩溃。这是堆栈溢出错误的最常见原因之一