二叉树叶子值的总和

时间:2019-07-11 18:03:35

标签: python recursion binary-tree

我编写了这段代码,当我使用print时,我看到了叶子。但是,该函数的最终返回值是None,而不是叶子的总和,在此示例中,叶子的总和应为7。我很高兴知道这里出了什么问题。谢谢!

class Node:
    def __init__(self, val=None):
        self.left = None
        self.right = None
        self.val = val


def sum_leafs(tree):
    if tree is None:
        return 0

    if tree.right and tree.left:
        sum_leafs(tree.right)
        sum_leafs(tree.left)

    elif tree.right or tree.left:
        if tree.right:
            sum_leafs(tree.right)
        elif tree.left:
            sum_leafs(tree.left)

    elif tree.right is None and tree.left is None:
        return sum_leafs(tree.left) + 1


node = Node(10)
node.right = Node(2)
node.left = Node(11)
node.left.right = Node(5)

print(sum_leafs(node))

4 个答案:

答案 0 :(得分:1)

在对分支(左/右)求和时,您忘记添加+,并且也忘记了访问val,这对于整个工作至关重要。

进一步,逻辑可以简化:

def sum_leafs(tree):
    if tree is None:
        return 0

    if not tree.right and not tree.left:
        return tree.val

    return sum_leafs(tree.right) + sum_leafs(tree.left)

答案 1 :(得分:0)

您没有将总和相加或归还。这也可以通过类中的方法来完成:

class Node:
    def __init__(self, val=None):
        self.left = None
        self.right = None
        self.val = val

    def sum(self):
        s = 0
        if self.left is not None:
            s += self.left.sum()
        if self.right is not None:
            s += self.right.sum()
        return self.val + s


node = Node(10)
node.right = Node(2)
node.left = Node(11)
node.left.right = Node(5)

print(node.sum())

返回:

28

答案 2 :(得分:0)

您没有正确返回计算出的叶子和。试试这个:

class Node:
    def __init__(self, val=None):
        self.left = None
        self.right = None
        self.val = val


def sum_leafs(tree):
    if tree is None:
        return 0

    elif tree.right and tree.left:
        return sum_leafs(tree.right) + sum_leafs(tree.left)

    elif tree.right or tree.left:
        if tree.right:
            return sum_leafs(tree.right)
        elif tree.left:
            return sum_leafs(tree.left)

    elif tree.right is None and tree.left is None:
        return tree.val

node = Node(10)
node.right = Node(2)
node.left = Node(11)
node.left.right = Node(5)

print(sum_leafs(node))
7

答案 3 :(得分:0)

首先,我将更新您的Node界面,以便在创建节点时可以设置leftright分支-

class Node:
  def __init__(self, val=None, left=None, right=None):
    self.left = left
    self.right = right
    self.val = val

这使我们可以更符合人体工程学地创建发束,例如-

t = Node(10, Node(11, None, Node(5)), Node(2))

现在,我们编写一个通用遍历过程。这使我们能够将1)树的遍历与2)我们要在每个树元素上执行的预期操作分开-

def traverse(tree):
  if tree is None:
    return
  else:
    yield tree.val
    yield from traverse(tree.left)
    yield from traverse(tree.right)

现在sum_leafs可以是一个简单程序。它不再需要关注树的遍历,而可以专注于将值的线性序列转换为所需的总和-

def sum_leafs(tree):
  r = 0
  for val in traverse(tree):
    r += val
  return r

print(sum_leafs(t))
# 28

或者,我们可以编写一个search函数来查找传递谓词的第一个值,而不是对这些值求和-

def search(test, tree):
  for val in traverse(tree):
    if test(val):
      return val

print(search(lambda x: x < 10, t))
# 5

print(search(lambda x: x > 99, t))
# None

或者,我们可以简单地将每个值收集到一个列表中-

print(list(traverse(t)))
# [ 10, 11, 5, 2 ]

如您所见,从依赖于我们的树的每个函数中删除遍历逻辑将是巨大的帮助。


如果您不喜欢生成器,则可以编写急切版本的traverse,该版本总是返回list。现在的区别是无法部分遍历树。请注意,该程序与生成器版本具有相似之处-

def traverse(tree):
  if tree is None:
    return [] # <-- empty
  else:
    return \
      [ tree.val
      , *traverse(tree.left)  # <-- yield from
      , *traverse(tree.right) # <-- yield from
      ]

print(traverse(t))
# [ 10, 11, 5, 2 ]