1

I've done a lot of searching, but none of the existing solutions solve my exact problem. I have a list:

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),
};

Here is the declaration for BuildTree() which currently does not work:

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;
}

Here is the call to BuildTree:

TreeNode rootNode = BuildTree(inputs);

So the BuildTree function has to return the root of the tree after building it. I've tried looping through the inputs. I've tried removing the first input from the list with each iteration. I can't quite figure it out. Any help would be greatly appreciated! Thank you!

2
  • so, it's a multileved tree, and what exactly is your problem (or what's not working?) Commented Nov 14, 2013 at 5:07
  • 1
    show us your ''input'' class too Commented Nov 14, 2013 at 5:10

1 Answer 1

1

You don't need recursion because you are transforming a list into a tree, not a tree into a list.

Since your input list is none of the standard tree traversals, and you did not tell us if parent nodes always come before child nodes, the easiest way we can use is a 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;
}
Sign up to request clarification or add additional context in comments.

2 Comments

My apologies, I should have stated that the inputs are always sorted so that no element references a parent id that did not previously existed in the collection. The solution works great. Thank you!
@user2990524 It's okay. Actually I would still suggest using a Dictionary since it's much easy to understand. The only difference is that you can remove the assignment of rootNode in the loop because you know it will come first.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.