【问题标题】:BST lookup recursion function confusion about returnsBST 查找递归函数关于返回的混淆
【发布时间】:2015-10-24 19:34:50
【问题描述】:

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

在本例中,查找函数返回两个值:(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' object is not iterable”。当我执行“return self.right.lookup(value, self)”和“return self.left.lookup(value, self)”时,TypeError 消失了,但我不明白为什么。为什么添加“return”会修复代码?

【问题讨论】:

  • 如果没有return,那么函数将返回None。保证。因此,不仅对lookup 的第一次调用是None,对lookup 的所有其他调用也是如此。

标签: python recursion


【解决方案1】:

如果没有返回语句,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

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

【讨论】:

    猜你喜欢
    • 2018-01-23
    • 2021-02-13
    • 1970-01-01
    • 2013-11-26
    • 2014-06-30
    • 2015-04-27
    • 1970-01-01
    • 2021-01-31
    相关资源
    最近更新 更多