How to flatten tree via LINQ?

后端 未结 14 2208
抹茶落季
抹茶落季 2020-11-22 04:56

So I have simple tree:

class MyNode
{
 public MyNode Parent;
 public IEnumerable Elements;
 int group = 1;
}

I have a I

14条回答
  •  误落风尘
    2020-11-22 05:34

    Most of the answers presented here are producing depth-first or zig-zag sequences. For example starting with the tree below:

            1                   2 
           / \                 / \
          /   \               /   \
         /     \             /     \
        /       \           /       \
       11       12         21       22
      / \       / \       / \       / \
     /   \     /   \     /   \     /   \
    111 112   121 122   211 212   221 222
    

    dasblinkenlight's answer produces this flattened sequence:

    111, 112, 121, 122, 11, 12, 211, 212, 221, 222, 21, 22, 1, 2
    

    Konamiman's answer (that generalizes Eric Lippert's answer) produces this flattened sequence:

    2, 22, 222, 221, 21, 212, 211, 1, 12, 122, 121, 11, 112, 111
    

    Ivan Stoev's answer produces this flattened sequence:

    1, 11, 111, 112, 12, 121, 122, 2, 21, 211, 212, 22, 221, 222
    

    If you are interested in a breadth-first sequence like this:

    1, 2, 11, 12, 21, 22, 111, 112, 121, 122, 211, 212, 221, 222
    

    ...then this is the solution for you:

    public static IEnumerable Flatten(this IEnumerable source,
        Func> childrenSelector)
    {
        var queue = new Queue(source);
        while (queue.Count > 0)
        {
            var current = queue.Dequeue();
            yield return current;
            var children = childrenSelector(current);
            if (children == null) continue;
            foreach (var child in children) queue.Enqueue(child);
        }
    }
    

    The difference in the implementation is basically using a Queue instead of a Stack. No actual sorting is taking place.


    Caution: this implementation is far from optimal regarding memory-efficiency, since a large percentage of the total number of elements will end up being stored in the internal queue during the enumeration. Stack-based tree-traversals are much more efficient regarding memory usage than Queue-based implementations.

提交回复
热议问题