【问题标题】:How to covert List to Tree without stack overflow如何在没有堆栈溢出的情况下将列表转换为树
【发布时间】:2017-01-23 15:57:42
【问题描述】:

我对 List[(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()))))

我发现列表中大数据的堆栈溢出

所以我想把它改成尾递归、映射或折叠

【问题讨论】:

  • 确保你的递归代码是尾递归的,否则会导致大输入时堆栈溢出
  • 请改成尾递归调用,我不知道该怎么做
  • Treevalue 属性是ID,对吧?
  • 是的,一个值为ID

标签: scala


【解决方案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】:

    DFStree 参数永远不会变小。因此,您永远不会达到基本情况。

    应该改为:DFS(tree.tail, x._1)

    【讨论】:

    • DFS(tree.tail, x._1) 与 DFS(tree, x._1) 相同
    【解决方案3】:

    虽然使其尾递归可能需要一些时间,但您可以按以下方式使其工作。

    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))))
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-01
      • 2018-11-13
      • 2012-04-23
      • 2014-03-14
      • 2018-03-29
      • 2016-08-30
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      相关资源
      最近更新 更多