コード例 #1
0
        /// <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);
        }