如何用尾部重新实现树遍历

时间:2018-04-27 18:15:38

标签: scala

我编写了简单的遍历函数:

case class Node(data: String, childs: Seq[Node] = Seq.empty)

def travers(root: Node, visit: String => Unit): Unit = {

  def recur(n: Node): Unit = {
    visit(n.data)
    for (c <- n.childs) recur(c)
  }

  recur(root)
}

val root = Node("1",
           Seq(Node("2",
               Seq(Node("3"), Node("4")))))

travers(root, s => println(s))

如何使用尾递归实现它?

2 个答案:

答案 0 :(得分:3)

你可以通过&#34;手动&#34;管理一堆要访问的节点,如下所示:

def travers(root: Node, visit: String => Unit): Unit = {

  @scala.annotation.tailrec
  def recur(stack: List[Node]): Unit = stack match {
    case Node(d, children) :: rest => {
      visit(d)
      recur(children.toList ++ rest)
    }
    case Nil => {}
  }

  recur(List(root))
}

答案 1 :(得分:2)

您可以尝试更改递归以在每次迭代时处理子项的序列 - 并获得广度优先遍历(与深度优先顺序@ JoeK&#不同39;答案和你的实施份额):

def travers(root: Node, visit: String => Unit): Unit = {
  @tailrec
  def recur(ns: List[Node]): Unit = {
    ns.foreach(n => visit(n.data))
    ns.flatMap(_.childs) match {
      case Nil => // done
      case more => recur(more)
    }
  }
  recur(List(root))
}