关于返回的{BST查找递归函数混淆

时间:2015-10-24 08:23:42

标签: python recursion

我正在尝试理解递归。这是关于在Python中实现BST的查找功能的一个非常基本的问题。此代码直接取自此post

在此示例中,lookup函数返回两个值:(1)树中是否存在该值;(2)如果在树中找到该值,则该值的父节点是什么。

为什么你需要做“return self.left.lookup(data,self)”?为什么你不能在没有返回的情况下做“self.left.lookup(data,self)”?

class Node:
    ...
    def lookup(self, data, parent=None):
        """
        Lookup node containing data

        @param data node data object to look up
        @param parent node's parent
        @returns node and node's parent if found or None, None
        """
        if data < self.data:
            if self.left is None:
                return None, None
            return self.left.lookup(data, self)
        elif data > self.data:
            if self.right is None:
                return None, None
            return self.right.lookup(data, self)
        else:
            return self, parent

我已经实现了一个查找的工作版本,它不会返回下面的值的父节点。以下工作正常,无需返回self.left.lookup():

def lookup(self, value):
    if(self.value == value):
        print("Found value!")
        return True
    elif self.value > value:
        if self.left == None:
            print("Value not found.")
            return False
        else:
            self.left.lookup(value)
    else:
        if self.right == None:
            print("Value not found.")
            return False
        else:
            self.right.lookup(value)

在下面的代码中,我尝试返回一个布尔值,表示值是否在树中以及父节点(就像原始帖子那样):

def lookup(self, value, parent=None):
    if(self.value == value):
        print("Found value!")
        return True, parent
    elif self.value > value:
        if self.left == None:
            print("Value not found.")
            return False, None
        else:
            self.left.lookup(value, self)
    else:
        if self.right == None:
            print("Value not found.")
            return False, None
        else:
            self.right.lookup(value, self)

上面的代码不起作用,我得到错误:“TypeError:'NoneType'对象不可迭代”。当我“返回self.right.lookup(value,self)”和“return self.left.lookup(value,self)”时,TypeError消失了,但我不明白为什么。为什么添加“return”修复代码?

1 个答案:

答案 0 :(得分:0)

如果没有return语句,python会自动返回None。你可以在python shell中测试它:

>>> def sum(a, b): a + b
>>> print sum(1, 2)
None

添加return语句告诉python将计算出的值返回给调用者:

>>> def sum(a, b): return a + b
>>> print sum(1, 2)
3

在你的情况下,结果是计算结果,但是一旦结束它将被丢弃,因为中间调用 lookup 没有返回计算结果。

为了说明玩具示例发生了什么,请考虑一个简单的递归乘法函数:

>>> def mult(n, m, acc=0):                                                                                                                                                           
      if m == 0: return acc                                                                                                                                                        
      else:
        print("m %s: %s" % (m, acc))                                                                                                                                         
        mult(n, m-1, acc+n)

此处对 mult 的中间调用不会返回递归步骤计算的结果。调用该函数会产生此输出:

>>> print mult(3, 3)
m 3: 0
m 2: 3
m 1: 6
None

正如您所看到的,结果是计算出来的,但是一旦最终结果准备就绪,一切都会被抛弃。

添加return语句:

>>> def mult(n, m, acc=0):                                                                                                                                                          
      if m == 0: return acc                                                                                                                                                        
      else:
        print("m %s: %s" % (m, acc))                                                                                                                                         
        return mult(n, m-1, acc+n)   

产生预期的产出:

print mult(3, 3)
m 3: 0
m 2: 3
m 1: 6
9

通常,递归函数的每一步必须按原样返回后续步骤的结果(尾递归)或以某种方式修改。