public Stack <StackNode> Merge(string identName)
        {
            Stack <StackNode> MergeOrder = new Stack <StackNode>();

            List <DictionaryNode> list = ResultTableRelations.dict[identName];

            int dictionaryNodeReference = list[0].Value;

            MergeOrder.Push(new StackNode(dictionaryNodeReference, -1));
            VisitedNode.Add(dictionaryNodeReference);
            VisitedName.Add(identName);

            if (list[0].KeyInRelatedNode != "$")
            {
                OrderQueue.Enqueue(list[0]);
                VisitedName.Add(list[0].KeyInRelatedNode);
            }

            for (int i = 1; i < list.Count; i++)
            {
                MergeOrder.Push(new StackNode(list[i].Value, dictionaryNodeReference));
                VisitedNode.Add(list[i].Value);
                VisitedName.Add(list[i].KeyInRelatedNode);

                if (list[i].KeyInRelatedNode != "$")
                {
                    OrderQueue.Enqueue(list[i]);
                    VisitedName.Add(list[i].KeyInRelatedNode);
                }
            }

            while (OrderQueue.Count > 0)
            {
                DictionaryNode top = OrderQueue.Dequeue();
                VisitedNode.Add(top.Value);

                list = ResultTableRelations.dict[top.KeyInRelatedNode];

                for (int i = 0; i < list.Count; i++)
                {
                    if (!VisitedNode.Contains(list[i].Value))
                    {
                        MergeOrder.Push(new StackNode(list[i].Value, top.Value));
                        VisitedNode.Add(list[i].Value);
                        VisitedName.Add(list[i].KeyInRelatedNode);

                        if (list[i].KeyInRelatedNode != "$")
                        {
                            OrderQueue.Enqueue(list[i]);
                        }
                    }
                }
            }

            return(MergeOrder);
        }
示例#2
0
 public override void Visit(Node node)
 {
     VisitingNode?.Invoke(this, node);
     base.Visit(node);
     VisitedNode?.Invoke(this, node);
 }
示例#3
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);
        }