2015-08-17 8 views
1

В настоящее время у меня есть дерево, и я использую код, найденный здесь Functionally traversing a tree in C#, чтобы получить пути в моем дереве. Дело в том, что этот код в настоящее время возвращает список каждого пути в моем дереве. Например, если у меня есть следующее дерево:Получить список путей дерева

A--- 
    | 
    ---B 
    | 
    ---C 
     | 
     ---D 
     | 
     ---E 

код будет возвращать {A}, {A, B}, {A, C}, {A, C, D}, {A, C, E}

где я действительно нуждаюсь в нем, чтобы просто вернуть ветви, т. Е. {A, B}, {A, C, D}, {A, C, E}.

Это не должно быть частью вышеприведенного метода, так же как и в конце, список, который я получаю, - это только ветви, а не каждый путь.

Что я действительно пытаюсь выяснить, как фильтровать список IEnumerable из приведенного выше метода, чтобы иметь только записи, в которых последний элемент в каждом списке не имеет детей.

Так что в моем текущем коде:

class Node 
{ 
    public string Name; 
    public int ParentID; 
    public List<Node> Children; 
} 

, а затем в моей основной код

List<Node> listOfNodes = getTreeNodes(); 

Node rootNode = listOfNodes.Where(n => n.ParentID == 0).FirstOrDefault(); 
// the below paths var will have every path instead of just the branches 
var paths = ComputePaths(rootNode, n=>n.Children); 

Используя код из связанного ответа:

static IEnumerable<IEnumerable<T>> ComputePaths<T>(T Root, Func<T, IEnumerable<T>> Children) { 
    yield return new[] { Root }; 
    foreach (var Child in Children(Root)) 
     foreach (var ChildPath in ComputePaths(Child, Children)) 
      yield return new[] { Root }.Concat(ChildPath);    
} 

Надежда, что имеет смысл. Любая помощь будет принята с благодарностью.

+0

Пожалуйста, разместите свой код первым. – Han

ответ

1

Это работает:

static IEnumerable<IEnumerable<T>> ComputePaths<T>(T Root, Func<T, IEnumerable<T>> Children) { 
    var children = Children(Root); 
    if (children != null && children.Any()) 
    { 
     foreach (var Child in children) 
      foreach (var ChildPath in ComputePaths(Child, Children)) 
       yield return new[] { Root }.Concat(ChildPath);    
    } else { 
     yield return new[] { Root }; 
    } 
} 

Если узел является узлом листа (без детей), мы возвращаем себя. В противном случае мы возвращаем путь своих детей.