Scala:如何计算二叉树叶子中所有元素的总和?

时间:2015-06-07 04:56:14

标签: scala sum binary-tree immutability case-class

我正在通过“Scala for the Impatient”一书中的练习来学习Scala。给定以下方法对case类的二叉树进行建模,一个问题要求计算叶子中所有元素的总和

sealed abstract class BinaryTree
case class Leaf(value: Int) extends BinaryTree
case class Node(left: BinaryTree, right: BinaryTree) extends BinaryTree

我的解决方案如下,并按预期工作。但是,我正在使用MutableList,因为Scala支持不变性,我想知道是否有办法使用List 来解决问题?

def leafSum(tree: BinaryTree): Int = {
  collectLeaves(tree) { MutableList[Int]() }.sum
}

private def collectLeaves(tree: BinaryTree)(leaves: MutableList[Int]): MutableList[Int] = tree match {
  case Node(left, right) =>
      collectLeaves(left)(leaves); collectLeaves(right)(leaves)
  case Leaf(value) => leaves += value
}

2 个答案:

答案 0 :(得分:4)

使用List并不是一个好主意,因为当您连接两个列表时,每次遇到Node时都必须复制其内容以进行O(n)复杂度操作。

如果你真的想用Lists做,你可以这样做:

def leafSum(tree: BinaryTree): Int = {
  collectLeaves(tree).sum
}

private def collectLeaves(tree: BinaryTree): List[Int] = tree match {
  case Node(left, right) => collectLeaves(left) ::: collectLeaves(right)
  case Leaf(value) => List(value)
}

虽然在我看来最好直接计算总和,因为你不需要在叶子中存储值:

def sum(tree: BinaryTree): Int = tree match {
  case Node(left, right) => sum(left) + sum(right)
  case Leaf(value) => value
}

答案 1 :(得分:3)

这是一种递归方法,不使用我认为相当优雅的辅助方法。请注意,它不是尾递归的,并且对于大输入将耗尽内存。

def leafSum(tree: BinaryTree): Int = tree match{
  case leaf:Leaf => leaf.value
  case node:Node => leafSum(node.left) + leafSum(node.right)
}