/// <summary> /// Performs a BFT of the graph with the given visitor and starting at the given vertex number. /// </summary> /// <param name="visitor"></param> /// <param name="start"></param> public virtual void BreadthFirstTraversal(IPrePostVisitor visitor, int start) { bool[] flags = new bool[mNumberOfVertices]; for (int i = 0; i < mNumberOfVertices; i++) { flags[i] = false; } IQueue queue = new QueueAsLinkedList(); queue.Enqueue(vertex[start]); flags[start] = true; while (!(queue.IsEmpty || visitor.IsDone)) { IVertex vertex1 = (IVertex)queue.Dequeue(); visitor.PreVisit(vertex1); Console.WriteLine("being in " + vertex1.Number); IEnumerator iEnumerator = vertex1.Successors.GetEnumerator(); try { while (iEnumerator.MoveNext()) { IVertex vertex2 = (IVertex)iEnumerator.Current; if (!flags[vertex2.Number]) { queue.Enqueue(vertex2); visitor.Visit(vertex2); Console.WriteLine("engueueing " + vertex2.Number); flags[vertex2.Number] = true; } } } finally { IDisposable iDisposable = iEnumerator as IDisposable; if (iDisposable != null) { iDisposable.Dispose(); } } visitor.PostVisit(vertex1); } }
/// <summary> /// /// </summary> /// <param name="tree"></param> public static void BreadthFirstTraversal(ITree tree) { IQueue queue = new QueueAsLinkedList(); if (!tree.IsEmpty) { queue.Enqueue(tree); } while (!queue.IsEmpty) { ITree tree2 = (ITree)queue.Dequeue(); Console.WriteLine(tree2.Key); for (int i = 0; i < tree2.Degree; i++) { ITree tree3 = tree2.GetSubtree(i); if (!tree3.IsEmpty) { queue.Enqueue(tree3); } } } }
/// <summary> /// Performs a BFT of the tree /// </summary> /// <param name="visitor"></param> public virtual void BreadthFirstTraversal(IVisitor visitor) { QueueAsLinkedList queue = new QueueAsLinkedList(); if (!base.IsEmpty) { queue.Enqueue(this); } while (!queue.IsEmpty && !visitor.IsDone) { ITree tree1 = (ITree)queue.Dequeue(); visitor.Visit(tree1.Key); for (int i = 0; i < tree1.Degree; i++) { ITree tree2 = tree1.GetSubtree(i); if (!tree2.IsEmpty) { queue.Enqueue(tree2); } } } }
/// <summary> /// This traversal visits the nodes of a directed graph in the order specified by a topological sort. /// Informally, a topological sort is a list of the vertices of a (directed) graph in which all the successors /// of any given vertex appear in the sequence after that vertex. /// </summary> /// <param name="visitor"></param> public virtual void TopologicalOrderTraversal(IVisitor visitor) { int[] nums1 = new int[(uint)mNumberOfVertices]; for (int i1 = 0; i1 < mNumberOfVertices; i1++) { nums1[i1] = 0; } IEnumerator iEnumerator = Edges.GetEnumerator(); try { while (iEnumerator.MoveNext()) { int[] nums2; int k; IVertex vertex1 = ((IEdge)iEnumerator.Current).V1; (nums2 = nums1)[k = vertex1.Number]++; } } finally { IDisposable iDisposable = iEnumerator as IDisposable; if (iDisposable != null) { iDisposable.Dispose(); } } IQueue queue = new QueueAsLinkedList(); // a cyclic graph might not have an entry point without in-edges //Thanks to Morton Mertner to fix this [email protected] int inEdges = 0; while (queue.IsEmpty || inEdges > mNumberOfEdges) { for (int j = 0; j < mNumberOfVertices; j++) { bool selectionCriteria = nums1[j] == inEdges; if (inEdges > 0) // cyclic graph - add nodes with cyclic refs first { foreach (IEdge e in vertex[j].EmanatingEdges) { selectionCriteria &= e.V0.Number == e.V1.Number; } } if (selectionCriteria) { queue.Enqueue(vertex[j]); } } inEdges++; } while (!(queue.IsEmpty || visitor.IsDone)) { IVertex vertex2 = (IVertex)queue.Dequeue(); visitor.Visit(vertex2); iEnumerator = vertex2.Successors.GetEnumerator(); try { while (iEnumerator.MoveNext()) { int[] nums2; int k; IVertex vertex3 = (IVertex)iEnumerator.Current; if ((nums2 = nums1)[k = vertex3.Number]-- == 0) { queue.Enqueue(vertex3); } } } catch (Exception exc) { System.Diagnostics.Trace.WriteLine(exc.Message, "AbstractGraph.TopologicalOrderTraversal"); } finally { IDisposable iDisposable = iEnumerator as IDisposable; if (iDisposable != null) { iDisposable.Dispose(); } } } }
internal Enumerator(QueueAsLinkedList queue) { this.queue = queue; }