Esempio n. 1
0
        /// <summary>
        // Walks a Node in a depth-first/pre-order manner without recursion.
        // It returns a series of "events" that indicate one of three things:
        // - whether it has enters into a node
        // - whether it has exited from a node (i.e. it is finished with that container and its children)
        /// </summary>
        /// <param name="node"></param>
        /// <param name="enum_children"></param>
        /// <param name="enter_node"></param>
        /// <returns></returns>
        public static IEnumerable <WalkEvent <T> > Walk <T>(T node, Traversal.EnumerateChildren <T> enum_children, EnterNode <T> enter_node)
        {
            var stack = new Stack <WalkState <T> >();

            // put the first item on the stack
            stack.Push(new WalkState <T>(node));

            // As long as something is on the stack, we are not done
            while (stack.Count > 0)
            {
                var cur_item = stack.Pop();

                if (cur_item.Entered == false)
                {
                    var walkevent = new WalkEvent <T>(cur_item.Node, WalkEventType.Enter);
                    yield return(walkevent);

                    cur_item.Entered = true;
                    stack.Push(cur_item);

                    if (enter_node(cur_item.Node))
                    {
                        foreach (var child in Traversal.efficient_reverse(enum_children(cur_item.Node)))
                        {
                            stack.Push(new WalkState <T>(child));
                        }
                    }
                }
                else
                {
                    var walkevent = new WalkEvent <T>(cur_item.Node, WalkEventType.Exit);
                    yield return(walkevent);
                }
            }
        }
Esempio n. 2
0
 public static IEnumerable <WalkEvent <T> > Walk <T>(T node, Traversal.EnumerateChildren <T> enum_children)
 {
     return(Walk(node, enum_children, n => true));
 }