我有列表[(nodeID,parentID)] - >的问题树结构
val tree: List[(Int, Int)] = List((1,0),(2,0),(3,0),(4,1),(5,4),(6,2),(7,6))
我的树案例类
case class Tree(value: Int, subTree: List[Tree])
我的代码
def DFS(tree: List[(Int, Int)], id: Int): List[Tree] = {
if(tree.isEmpty) Nil
else List(Tree(id, tree.filter(x => x._2 == id).flatMap(x => DFS(tree, x._1))))}
结果
List(Tree(0,List(Tree(1,List(Tree(4,List(Tree(5,List()))))), Tree(2,List(Tree(6,List(Tree(7,List()))))), Tree(3,List()))))
我发现列表中的大数据堆栈溢出
所以我想把它改成尾递归,贴图或折叠
答案 0 :(得分:1)
tree
DFS
参数永远不会变小。因此,您永远不会遇到基本情况。
请拨打电话:DFS(tree.tail, x._1)
?
答案 1 :(得分:1)
从性能的角度来看,还有很多需要改进的地方,但似乎有效:
val tree: List[(Int, Int)] = List((1,0),(2,0),(3,0),(4,1),(5,4),(6,2),(7,6))
case class Tree(value: Int, subTree: List[Tree])
// Sort in reverse BFS order
@annotation.tailrec
def BFS(tree: List[(Int, Int)], ids: List[(Int, Int)], acc: List[(Int, Int)]): List[(Int, Int)] = {
ids match {
case Nil => acc
case head::tail =>
BFS(tree, tail ++ tree.filter(_._2 == head._1), head::acc)
}
}
// acc: List of (parent, Tree)
@annotation.tailrec
def fold(bfs: List[(Int, Int)], acc: List[(Int, Tree)]): List[(Int, Tree)] = {
bfs match {
case Nil => acc
case head::tail =>
val (l, r) = acc.partition(_._1 == head._1)
fold(tail, (head._2, Tree(head._1, l.map(_._2))) :: r)
}
}
fold(BFS(tree, List((0, 0)), Nil), Nil).map(_._2)
答案 2 :(得分:0)
尽管使尾部递归可能需要一些时间,但您可以按照以下方式进行操作。
val tree: List[(Int, Int)] = List((1,0),(2,0),(3,0),(4,1),(5,4),(6,2),(7,6))
def DFS(tree: List[(Int, Int)], id: Int): List[Tree] = tree match {
case Nil => List[Tree]()
case list =>
val (children, others) => list.partition(x => x._2 == id)
List(Tree(id, children.flatMap(x => DFS(others, x._1))))
}