2013-11-14 9 views
0

Я много раз искал, но ни одно из существующих решений не решило мою точную проблему. У меня есть список:Построение дерева из списка с помощью рекурсии

Input[] inputs = new Input[] 
{ 
    new Input(1), 
    new Input(3,1), 
    new Input(19,3), 
    new Input(22,1), 
    new Input(4,1), 
    new Input(5,22), 
}; 

Вот декларация для BuildTree(), которая в настоящее время не работает:

public TreeNode BuildTree(IEnumerable<Input> inputs, TreeNode parentNode = null) 
{ 
    List<Input> nodes = inputs.ToList<Input>(); 

    foreach (Input node in nodes) 
    { 
     TreeNode newNode = new TreeNode(node.Id); 
     if (parentNode == null) 
     { 
      parentNode = BuildTree(nodes, newNode); 
     } 
     else 
     { 
      parentNode.AddChild(newNode); 
     } 
    } 

    return parentNode; 
} 

Вот вызов BuildTree:

TreeNode rootNode = BuildTree(inputs); 

Так BuildTree функция должна вернуть корень дерева после его создания. Я пробовал перебирать входные данные. Я попытался удалить первый вход из списка с каждой итерацией. Я не могу это понять. Любая помощь будет принята с благодарностью! Спасибо!

+0

так, это multileved дерево, и что именно ваша проблема (или то, что не работает?) – Noctis

+1

показать нам свой класс «» вход «» слишком – jhyap

ответ

0

Вам не нужна рекурсия, потому что вы преобразовываете список в дерево, а не дерево в список.

Поскольку ваш список входных данных не является стандартным обходным деревом, и вы не сказали нам, что родительские узлы всегда идут до дочерних узлов, самым простым способом мы можем воспользоваться Dictionary.

public TreeNode BuildTree(IEnumerable<Input> inputs) 
{ 
    TreeNode rootNode = null; 
    // Build a dictionary to store each input and its node 
    var dict = inputs.ToDictionary(
     input => input.Id, 
     input => new { Input = input, Node = new TreeNode(input.Id.ToString()) }); 

    // Iterate through the nodes and build relationship among them 
    foreach(var value in dict.Values) 
    { 
     var input = value.Input; 
     if(input.ParentId != null) 
     { 
      dict[(int)input.ParentId].Node.Nodes.Add(value.Node); 
     } 
     else 
     { 
      rootNode = value.Node; 
     } 
    } 
    return rootNode; 
} 
+0

Мои извинения, я бы сказал, что входы всегда сортируются так, чтобы ни один элемент не ссылался на родительский идентификатор, который ранее не существовал в коллекции. Решение отлично работает. Спасибо! – user2990524

+0

@ user2990524 Все в порядке. На самом деле я бы все же предложил использовать «Словарь», так как это очень легко понять. Единственное различие заключается в том, что вы можете удалить назначение «rootNode» в цикле, потому что знаете, что это произойдет первым. – Gildor

Смежные вопросы