Je vais supposer que la structure de votre arbre ressemble à ceci:
class Node<T> {
public readonly T Value;
public readonly LinkedList<Node<T>> Children;
public readonly bool IsEmtpy;
public Node() {
IsEmpty = true;
}
public Node(T value, LinkedList<Node<T>> children) {
Value = value;
Children = children;
IsEmpty = false;
}
}
Vous pouvez filtrer votre arbre en un seul passage avec une première recherche en profondeur.
Je trouve généralement plus facile de prototyper ces sortes d'algorithmes dans un langage fonctionnel, puis de les traduire en C# lorsque cela est nécessaire. Voici le code F #:
type 'a tree = Nil | Node of 'a * 'a tree list
// val filter : ('a -> bool) -> 'a tree list -> 'a tree list
let rec filter f = function
| Node(value, children)::xs ->
if f value then Node(value, filter f children)::filter f xs
else (filter f children) @ filter f xs
| Nil::xs -> filter f xs
| [] -> []
let input =
Node("A1",
[ Node("B1",
[ Node("B2", []);
Node("A2",
[ Node("A3", []);
Node("B3", [ Node("A4", []) ]) ]) ]);
Node("A5", []);
Node("C1",
[ Node("C2",
[Node("C3", [ Node("A6", []) ]) ]) ]) ])
let expectedOutput =
Node("A1",
[ Node("A2",
[ Node("A3", []);
Node("A4", []) ]);
Node("A5", []);
Node("A6", []) ])
let actualOutput = [input] |> filter (fun value -> value.StartsWith("A")) |> List.head
let testPasses = expectedOutput = actualOutput
Et la sortie F #:
val testPasses : bool = true
Et voici le code équivalent en C#:
static LinkedList<Node<T>> Filter(Func<T, bool> predicate, IEnumerable<Node<T>> input) {
var res = new LinkedList<Node<T>>();
foreach(Node<T> node in input) {
if (!node.IsEmpty) {
if (predicate(node.Value)) {
res.AddLast(new Node(node.Value, Filter(predicate, node.Children));
else {
res.AddRange(Filter(predicate, node.Children));
}
}
}
return res;
}
On ne sait pas si votre arbre a une structure conçue à partir de la nœuds? Le fait? –