如何从节点路径列表中优化构建树?

时间:2019-03-24 19:40:41

标签: algorithm scala optimization tree

假设我正在编写一个函数fromPaths(paths: List[String]): Node,以从几个这样的节点路径构建树:

case class Node(value: String, children: List[Node])
val paths = List("a/b/x", "a/b/y", "a/c", "a/c/d")
fromPaths(paths) // Node("a", List(Node("b", List(Node("x"), Node("y"))), Node("c", List(Node("d")))))

我可以编写一个函数addNode(root: Node, path: String): Node,然后将其fold放在列表中。但是,由于我们针对root中的每个“路径”将树从node遍历到paths,因此看起来不太理想。

您如何针对遍历的节点总数优化fromPaths

1 个答案:

答案 0 :(得分:2)

至少在您的示例中,明显的递归似乎还不错:

case class Node[A](a: A, children: List[Node[A]])
def trieForest[A](lists: List[List[A]]): List[Node[A]] = {
  lists.filter(_.nonEmpty).groupBy(_.head).map { 
    case (k, vs) =>
    Node(k, trieForest(vs.map(_.tail)))
  }.toList
}

def fromPaths(paths: List[String]): Node[String] = {
  // assumes that there is only one tree in the 
  // top-level forest.
  trieForest(paths.map(_.split("/").toList)).head
}

println(fromPaths(List("a/b/x", "a/b/y", "a/c", "a/c/d")))

打印(最多缩进):

Node(a, List(
  Node(b,List(
    Node(y,List()), 
    Node(x,List())
  )),
  Node(c,List(
    Node(d,List())
  ))
))

它不能渐近运行,因为您必须至少一次查看输入的每个部分。