То, что вам нужно, - это базовая функция обхода дерева (предварительный заказ, внутренний или почтовый заказ - это не имеет значения) и функция фильтра. Затем вы можете собрать эти два вместе и получить то, что вам нужно:
IEnumerable<T> Traverse(Tree<T> tree)
{
yield return tree.Data;
foreach(Tree<T> subtree in tree.Subtrees)
foreach(T t in Traverse(subtree))
yield return t;
}
IEnumerable<U> Filter<T, U>(IEnumerable<T> source)
where U : T
{
foreach(T t in source)
if(t is U)
yield return (U)t;
}