/// <summary> /// Visits all recheable nodes in correct order. /// </summary> /// <remarks> /// Graph must be directed, acyclic. /// </remarks> /// <typeparam name="T">The type of graph vertex.</typeparam> /// <param name="node">The beginning node.</param> /// <param name="graph">The graph structure.</param> /// <returns>Listed nodes in correct order.</returns> public static List <uint> ListNodesInOrder(uint node, [NotNull] IGraph graph) { List <uint> orderedNodes = new List <uint>(); // We keep track of visited nodes and how many times they were visited. // We proceed when count is the same as number of links to that node. List <VisitedNode> visitedNode = new List <VisitedNode>(10); Stack <SearchData> stack = new Stack <SearchData>(); stack.Push(new SearchData(node, graph.NextNodes(node))); // We also add first. orderedNodes.Add(node); // Until we finish. while (true) { // We can exit. if (stack.Count == 0) { break; } SearchData search = stack.Pop(); if (search.Next(out node)) { // It is still useful. stack.Push(search); // We have next in node. We check if we can proceed. uint order = graph.Order(node); if (order == 1) { // We can insert it here, it is ordered. orderedNodes.Add(node); stack.Push(new SearchData(node, graph.NextNodes(node))); continue; } // We have to make sure we add the count to visited. First check // if it exists. bool found = false; for (int i = 0; i < visitedNode.Count; ++i) { // We found it. if (visitedNode[i].node == node) { visitedNode[i].visitCount++; if (visitedNode[i].visitCount >= order) { // We can insert it here, it is ordered. orderedNodes.Add(node); stack.Push(new SearchData(node, graph.NextNodes(node))); } found = true; break; } } // We may already found it. if (found) { continue; } // We must add it if not found. VisitedNode vnode = new VisitedNode(); vnode.node = node; vnode.visitCount = 1; visitedNode.Add(vnode); } } return(orderedNodes); }