Reputation: 4685
I wrote simple traversal function:
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))
How to implement it with tail recursion?
Upvotes: 1
Views: 142
Reputation: 37832
You can try changing the recursion to handle a sequence of children at each iteration - and get a breadth-first traversal (unlike the depth-first order @JoeK's answer and your implementation share):
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))
}
Upvotes: 2
Reputation: 18424
You could do this by "manually" managing a stack of nodes to visit, like this:
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))
}
Upvotes: 3