【发布时间】:2016-05-04 12:24:35
【问题描述】:
我已经在 Scala 中实现了一个基本的可变树,我想以一种函数式的方式遍历它以搜索一个元素,但我不知道如何实现它。如果可能的话,我还希望算法是尾递归的。
树是一个结构,它有一个值和一个叶子列表,叶子也是树。
任何帮助将不胜感激。
这是我拥有的代码(专注于 getOpt 方法):
package main
import scala.collection.mutable.ListBuffer
sealed trait Tree[Node] {
val node: Node
val parent: Option[Tree[Node]]
val children: ListBuffer[Tree[Node]]
def add(n: Node): Tree[Node]
def size: Int
def getOpt(p: (Node) => Boolean): Option[Tree[Node]]
override def toString = {
s"""[$node${if (children.isEmpty) "" else s", Children: $children"}]"""
}
}
case class ConcreteTree(override val node: Int) extends Tree[Int] {
override val children = ListBuffer[Tree[Int]]()
override val parent: Option[Tree[Int]] = None
override def add(n: Int): ConcreteTree = {
val newNode = new ConcreteTree(n) {override val parent: Option[Tree[Int]] = Some(this)}
children += newNode
newNode
}
override def size: Int = {
def _size(t: Tree[Int]): Int = {
1 + t.children.foldLeft(0)((sum, tree) => sum + _size(tree))
}
_size(this)
}
// This method is not correct
override def getOpt(p: (Int) => Boolean): Option[Tree[Int]] = {
def _getOpt(tree: Tree[Int], p: (Int) => Boolean): Option[Tree[Int]] = {
tree.children.map {
t =>
if(p(t.node)) Some(t) else t.children.map(_getOpt(_, p))
}
}
}
}
object Main {
def main(args: Array[String]) {
val tree1 = ConcreteTree(1)
val tree2 = tree1.add(2)
val tree3 = tree1.add(3)
println(tree1.getOpt(_ == 2))
}
}
@doertsch 的回答是我目前最好的方法。
【问题讨论】:
-
一个简单的按顺序遍历应该可以。除非树是有序的
-
你试过写代码吗?
-
@Archeg 是的,我知道如何以 OOP 方式进行操作,但我不知道如何以功能方式进行操作。例如,a 不能映射到叶子列表上,因为我想返回 Option[Tree[]] 但它会导致 ListBuffer[Option[Tree[]]] 并且我也想要找到结果时完成。
-
@vicaba 那么请发布您尝试过的代码,我们会尽力帮助您解决问题。
-
@Archeg 我已经添加了代码。
标签: algorithm scala data-structures tree functional-programming