Voyons voir des solutions Scala.Tout d'abord, je vais définir un arbre binaire très basique:
case class Tree[+T](value: T, left: Option[Tree[T]], right: Option[Tree[T]])
Nous allons utiliser l'arbre suivant:
1
/\
2 3
//\
4 5 6
Vous définissez l'arbre comme ceci:
val myTree = Tree(1,
Some(Tree(2,
Some(Tree(4, None, None)),
None
)
),
Some(Tree(3,
Some(Tree(5, None, None)),
Some(Tree(6, None, None))
)
)
)
Nous » ll définira une fonction breadthFirst qui traversera l'arbre en appliquant la fonction désirée à chaque élément. Avec cela, nous allons définir une fonction d'impression et l'utiliser comme ceci:
def printTree(tree: Tree[Any]) =
breadthFirst(tree, (t: Tree[Any]) => println(t.value))
printTree(myTree)
Maintenant, la solution Scala, listes récursive, mais pas les files d'attente:
def breadthFirst[T](t: Tree[T], f: Tree[T] => Unit): Unit = {
def traverse(trees: List[Tree[T]]): Unit = trees match {
case Nil => // do nothing
case _ =>
val children = for{tree <- trees
Some(child) <- List(tree.left, tree.right)}
yield child
trees map f
traverse(children)
}
traverse(List(t))
}
Ensuite, la solution Scala, file d'attente, pas récursion:
def breadthFirst[T](t: Tree[T], f: Tree[T] => Unit): Unit = {
import scala.collection.mutable.Queue
val queue = new Queue[Option[Tree[T]]]
import queue._
enqueue(Some(t))
while(!isEmpty)
dequeue match {
case Some(tree) =>
f(tree)
enqueue(tree.left)
enqueue(tree.right)
case None =>
}
}
cette solution récursive est entièrement fonctionnelle, bien que j'ai un sentiment de malaise qu'il peut être encore simplifiée.
La version de la file d'attente n'est pas fonctionnelle, mais elle est très efficace. Le truc sur l'importation d'un objet est inhabituel dans Scala, mais mis à profit ici.
Je serais surpris si quelqu'un avait une solution qui était plus lisible qu'une BFS de l'arbre ... – Eric
http://en.wikipedia.org/wiki/Tree_traversal#Queue-based_level_order_traversal – CodeFusionMobile