假设我有一个带有子类abstract BinaryTree
和Node
的简单Leaf
,我想写一个产生List[Leaf]
的函数。
def getLeaves(tree: BinaryTree): List[Leaf] =
tree match {
case Leaf(v) => List(tree.asInstanceOf[Leaf])
case Node(left, right) => getLeaves(left) ++ getLeaves(right)
}
有没有办法避免在asInstanceOf[Leaf]
案例中明确Leaf
强制转换?如果我把它遗漏,我得到一个诊断说法:发现:BinaryTree;需要Leaf。
答案 0 :(得分:8)
我在其他地方看过这个结构。它似乎可以完成这项工作。
def getLeaves(tree: BinaryTree): List[Leaf] =
tree match {
case leaf: Leaf => List(leaf)
case Node(left, right) => getLeaves(left) ++ getLeaves(right)
}
答案 1 :(得分:3)
试试这种方式
def getLeaves(tree: BinaryTree): List[Leaf] =
tree match {
case x@Leaf(v) => List(x)
case Node(left, right) => getLeaves(left) ++ getLeaves(right)
}
另请注意,由于您要在每个节点中创建新列表,因此您的实施在性能方面表现不佳。
可以通过这种方式修复
def genLeaves(tree:BinaryTree) = {
def getLeaves0(tree: BinaryTree, acc:List[Leaf]): List[Leaf] =
tree match {
case x@Leaf(v) => x::acc
case Node(left, right) => {
val leftLeaves = getLeaves(left, acc)
getLeaves(right, leftLeaves)
}
}
getLeaves0(tree).reverse
}
下面'您将重复使用已收集的所有项目,并且您在遍历期间只会分配一个列表。您在遍历它时会收集元素,因此您将以相反的顺序结束Leaf(List作为LIFO),因此要按照您访问它的方式获取元素,我们需要反转结果列表。
答案 2 :(得分:1)
您可以利用已经解构tree
至Leaf(v)
的事实,并重建树叶:
def getLeaves(tree: BinaryTree): List[Leaf] =
tree match {
case Leaf(v) => List(Leav(v))
case Node(left, right) => getLeaves(left) ++ getLeaves(right)
}