【问题标题】:Ruby: Calculate sum of all node values of a binary treeRuby:计算二叉树的所有节点值的总和
【发布时间】:2019-03-06 00:32:12
【问题描述】:

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

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 没有。

【问题讨论】:

  • 你是什么意思,你找到了其他语言的答案,但没有找到 Ruby?逻辑完全一样。您在实施过程中面临的具体障碍是什么?
  • @Amadan 我是一名初学者并试图理解递归。虽然我确实了解原理,但我无法将其他语言的解决方案转换为 Ruby...
  • 一个节点的总和是该节点的值加上所有非零子节点的总和,对吧?至少试着把它翻译成代码,然后我们可以谈谈它有什么问题,如果有的话。
  • 一个好的开始是添加一个树的例子(并显示所需总和的值)。由于还没有答案,您可能会考虑删除问题,编辑以澄清并添加示例,然后取消删除。这样您就不会感到完成编辑的时间压力,也不会在编辑时吸引更多的反对票或关闭投票。 SO 有一条规则,对于家庭作业问题(不是暗示这是一个),提问者应该解释他/她为解决问题所做的努力。这不一定需要代码。这可能是一个好问题。
  • 回复:“节点的总和是节点的值加上所有非零子节点的总和,对吗?至少尝试将其转换为代码”。这是我在 BST 类中尝试的内容:def sum(node=@root) return if node.nil? total += node.value sum(node.left) sum(node.right) end 但是它会抛出“NoMethodError: undefined method `+' for nil:NilClass”。这就是我卡住的地方。

标签: ruby sum binary-tree


【解决方案1】:

我认为您在 cmets 中的代码是:

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 与某物相加,则效果不佳。这里有两种解决方案:在输入之前拒绝对一个节点求和,或者说一个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

【讨论】:

  • 非常感谢您的详细解答!它准确地解释了我一直在努力解决的所有问题,让我挠头好几天,直到我最终求助于 SO。还要感谢您指导我使用 SO,还要感谢 @Cary!附言由于我的声誉得分太低,我的点赞尝试没有被记录下来……再次感谢 - 你非常有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多