Ruby:计算二叉树的所有节点值的总和

时间:2019-03-06 00:32:13

标签: ruby sum binary-tree

我有如下的二叉树实现。我想添加一个递归总结二叉树所有节点值的方法:

class BST

  class Node
    attr_reader :value, :left, :right

    def initialize(value)
      @value = value
      @left = nil
      @right = nil
    end

    def insert(value)
      if value <= @value
        @left.nil? ? @left = Node.new(value) : @left.insert(value)
      elsif value > @value
        @right.nil? ? @right = Node.new(value) : @right.insert(value)
      end
    end

  end

  def initialize
    @root = nil
  end

  def insert(value)
    @root.nil? ? @root = Node.new(value) : @root.insert(value)
  end

end

我找到了其他语言的答案,但是不幸的是,不是Ruby。

1 个答案:

答案 0 :(得分:0)

我认为您在注释中的代码是:

def sum(node=@root)
  return if node.nil?
  total += node.value
  sum(node.left)
  sum(node.right)
end

这个想法几乎可以。 nil个节点中没有求和;然后将当前节点(左节点和右节点)的值相加。这是错误:

  • total += node.value是我们第一次看到total。这会将其初始化为nil。当您尝试向其中添加node.value时,您将得到描述的错误。为了避免这种情况,total必须已经存在,或者您可以分配 node.value

  • 如果函数在没有执行return语句的情况下结束,则它将返回最后一个求值的表达式;在这种情况下,sum(node.right)sum返回total会更好吗?

  • 相反,sum(node.left)可能会进行一些求和...但是其返回值将被丢弃。将其添加到total中可能很有意义。说到总数,也许我们应该对sum(node.right)做同样的事情。

  • 最后,return if node.nil?说您拒绝对实际上不是节点的节点求和。太好了……除了return返回nil之外,如果您尝试将nil与某物相加,则效果不佳。这里有两种解决方案:拒绝在输入之前总计一个节点,或者说一个零节点的值为0,这不会影响总和。

综合考虑,这是我的两个版本:

# refuse to enter a nil node:
def sum(node=@root)
  total = node.value
  total += sum(node.left) unless node.left.nil?
  total += sum(node.right) unless node.right.nil?
  total
end

# treat nil nodes as if they were zeroes:
def sum(node=@root)
  return 0 if node.nil?
  node.value + sum(node.left) + sum(node.right)
end