我有一个节点树:
val root = Node("a", List(Node("w", Nil), Node("b", List(Node("c", List(Node("d", Nil))), Node("m", List(Node("n", Nil)))))))
和中间节点列表:
val ks = List("b", "m")
引导我到我必须添加节点的位置:
val child = Node("t", Nil)
导致:
val res = Node("a", List(Node("w", Nil), Node("b", List(Node("c", List(Node("d", Nil))), Node("m", List(Node("n", Nil), Node("t", Nil)))))))
Scala中的树被建模为:
sealed trait Tree[A]
case class Empty[A]() extends Tree[A]
case class Node[A](rootNode: A, subtree: List[Tree[A]]) extends Tree[A]
我尝试遍历树并添加节点,
@tailrec
def traverseAndAdd(root: Node[String], subNode: Node[String], child: Node[String], ls: List[String]): Node[String] = ls match {
case Nil =>
root
case x :: Nil =>
val k = subNode.subtree.filter(l => l.asInstanceOf[Node[String]].rootNode == x).head.asInstanceOf[Node[String]].subtree :+ child
println(k)
traverseAndAdd(root, subNode, child, Nil)
case x :: xs =>
traverseAndAdd(root, subNode.subtree.filter(l => l.asInstanceOf[Node[String]].rootNode == x).head.asInstanceOf[Node[String]], child, xs)
}
val root = Node("a", List(Node("w", Nil), Node("b", List(Node("c", List(Node("d", Nil))), Node("m", List(Node("n", Nil)))))))
val child = Node("t", Nil)
val ks = List("b", "m")
println("res: " + traverseAndAdd(root, root, child, ks))
我知道这里的列表是不可变的,甚至代码也没有尝试构建节点。我想要一个关于如何在Scala中实现这样的事情的建议。请帮忙。
另外,我已经尝试过这个问题,这个问题是使用正常(非尾部)递归的子问题,但我最终得到的数据堆栈流量是巨大的。所以想到这种方法!
答案 0 :(得分:1)
我注意到您的代码中存在一些缺点。
class Empty
已定义但从未使用过。val k
已填充但从未使用过。这是我能够构建的。它不是尾递归,也不是解决唯一性问题,但似乎有效。
case class Node[A](elem: A, subNodes: List[Node[A]])
def addNode[T](node: Node[T], path: List[T]): Node[T] = {
if (path.isEmpty)
node
else if (path.head == node.elem)
addNode(node, path.tail)
else if (node.subNodes.map(_.elem).contains(path.head))
Node(node.elem, node.subNodes.map{n =>
if (n.elem == path.head) addNode(n,path.tail)
else n
})
else
Node(node.elem
,node.subNodes :+ addNode(Node(path.head, List[Node[T]]()), path.tail))
}
val root = Node("a", List(Node("w", Nil)
,Node("b", List(Node("c", List(Node("d", Nil)))
,Node("m", List(Node("n", Nil)))))))
addNode(root,List("a","b","m","n","t"))