Ejemplo n.º 1
0
        // <summary>
        // Walk the graph like it was a tree from the root - if you encounter a cycle, stop further walking
        // and continue with the next node
        // </summary>
        // <param name="opeartion"></param>
        // <param name="state"></param>
        public void BreadthFirstSearchOperation(GraphNodeOperationDelegate operation, object state)
        {
            Queue <IGraphNode> pendingNodes = new Queue <IGraphNode>();

            pendingNodes.Enqueue(this);
            List <IGraphNode> visitedNodes = new List <IGraphNode>();

            while (pendingNodes.Count != 0)
            {
                IGraphNode node = pendingNodes.Dequeue();
                if (visitedNodes.Contains(node))
                {
                    // cycle - already seen this node //
                    continue;
                }
                else
                {
                    visitedNodes.Add(node);
                }

                operation(node, state);

                foreach (IGraphNode child in node.Children)
                {
                    pendingNodes.Enqueue(child);
                }
            }
        }
Ejemplo n.º 2
0
        public void DepthFirstSearchOperation(GraphNodeOperationDelegate preVisit, GraphNodeOperationDelegate postVisit, object state)
        {
            // nothing happens unless one operation is provided
            if (preVisit == null && postVisit == null)
            {
                return;
            }

            // we must be able to distinguish these for the algorithm below to work
            if (preVisit == postVisit)
            {
                throw new InvalidOperationException("Operations must be different.");
            }

            List <IGraphNode>          visitedNodes = new List <IGraphNode>();
            Stack <DepthFirstWalkInfo> frames       = new Stack <DepthFirstWalkInfo>();

            frames.Push(new DepthFirstWalkInfo {
                CurrentNode = this, Operation = preVisit
            });

            while (frames.Count > 0)
            {
                DepthFirstWalkInfo current = frames.Pop();

                if (visitedNodes.Contains(current.CurrentNode))
                {
                    if (current.Operation == preVisit)
                    {
                        continue;
                    }
                }
                else
                {
                    visitedNodes.Add(current.CurrentNode);
                }


                if (current.Operation != null)
                {
                    current.Operation(current.CurrentNode, state);
                }

                if (current.Operation != postVisit)
                {
                    frames.Push(new DepthFirstWalkInfo {
                        CurrentNode = current.CurrentNode, Operation = postVisit
                    });

                    // this goes into the stack in reverse order of what we need,
                    // put onto one stack then another to reverse it
                    Stack <DepthFirstWalkInfo> tempStack = new Stack <DepthFirstWalkInfo>();
                    foreach (IGraphNode child in current.CurrentNode.Children)
                    {
                        tempStack.Push(new DepthFirstWalkInfo {
                            CurrentNode = child, Operation = preVisit
                        });
                    }

                    while (tempStack.Count > 0)
                    {
                        frames.Push(tempStack.Pop());
                    }
                }
            }
        }
Ejemplo n.º 3
0
 public void DepthFirstSearchOperation(GraphNodeOperationDelegate operation, object state)
 {
     DepthFirstSearchOperation(operation, null, state);
 }