예제 #1
0
        private void BFSImpl(ReadOnlyNode startNode, Action <ReadOnlyNode> map)
        {
            var queue = new Queue <Node>();
            var start = startNode.ThisNode as Node;

            start.Distance = 0;
            queue.Enqueue(start);
            while (queue.Count > 0)
            {
                var node = queue.Dequeue();
                map?.Invoke(ReadOnlyNode.Create(node).Value);
                node.Color = NodeColor.Black; // seen and leaving
                foreach (var edge in node.OutEdges)
                {
                    var targetNode = edge.NodeTo.ThisNode as Node;
                    if (targetNode.Color == NodeColor.White)
                    {
                        targetNode.Color        = NodeColor.Gray; // seen and has not left yet
                        targetNode.Distance     = node.Distance + 1;
                        targetNode.PreviousNode = node;
                        queue.Enqueue(targetNode);
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Add value to graph and create node for it.
        /// </summary>
        /// <param name="value">Value to add</param>
        /// <returns>Node created for this value</returns>
        public ReadOnlyNode AddNode(T value)
        {
            var node = new Node(value);

            nodes.Add(node);
            return(ReadOnlyNode.Create(node).Value);
        }
예제 #3
0
 /// <summary>
 /// Remove all nodes that match given predicate.
 /// </summary>
 /// <param name="predicate">Predicate to match</param>
 public void RemoveAllNodes(Predicate <ReadOnlyNode> predicate)
 {
     if (predicate == null)
     {
         throw new ArgumentNullException("Predicate is null");
     }
     nodes.RemoveAll(node => predicate(ReadOnlyNode.Create(node).Value));
 }
예제 #4
0
        /// <summary>
        /// Find node with given key.
        /// </summary>
        /// <param name="key">Key of node to find</param>
        /// <returns>Node that contains given key if any found, otherwise null</returns>
        public ReadOnlyNode?Find(TKey key)
        {
            var result = FindNodeImpl(key);

            if (result.Node != null)
            {
                Splay(result.Node);
            }
            return(ReadOnlyNode.Create(result.Node));
        }
예제 #5
0
 /// <summary>
 /// Get node at given index.
 /// </summary>
 /// <param name="index">Node's index</param>
 /// <returns>Node at given index</returns>
 public ReadOnlyNode this[int index]
 {
     get
     {
         if (index < 0 || index >= Count)
         {
             throw new ArgumentOutOfRangeException("Index out of range");
         }
         return(ReadOnlyNode.Create(nodes[index]).Value);
     }
 }
예제 #6
0
        /// <summary>
        /// Find all nodes with values that match given predicate.
        /// </summary>
        /// <param name="predicate">Predicate</param>
        /// <returns>List of nodes that match given predicate</returns>
        public List <ReadOnlyNode> FindAll(Predicate <T> predicate)
        {
            var list = new List <ReadOnlyNode>();
            var node = FindFrom(predicate, frontNode);

            while (node != null)
            {
                list.Add(ReadOnlyNode.Create(node).Value);
                node = FindFrom(predicate, node.Next);
            }
            return(list);
        }
예제 #7
0
        /// <summary>
        /// Count number connectivity components in graph using BFS.
        /// </summary>
        /// <returns>Number of connectivity components in graph</returns>
        public int NumberOfConnectivityComponents()
        {
            PrepareForGraphTraverse();
            int componentsCounter = 0;

            foreach (var node in nodes)
            {
                if (node.Color == NodeColor.White)
                {
                    componentsCounter++;
                    BFS(ReadOnlyNode.Create(node).Value, null);
                }
            }
            ClearTraversingStats();
            return(componentsCounter);
        }
예제 #8
0
        /// <summary>
        /// Remove first node that match given predicate.
        /// </summary>
        /// <param name="predicate">Predicate to match</param>
        /// <returns>True if any node was removed, false otherwise</returns>
        public bool RemoveNode(Predicate <ReadOnlyNode> predicate)
        {
            if (predicate == null)
            {
                throw new ArgumentNullException("Predicate is null");
            }
            var index = nodes.FindIndex(node => predicate(ReadOnlyNode.Create(node).Value));

            if (index >= 0 && index < Count)
            {
                RemoveAllEdgesConnectedToNode(nodes[index]);
                nodes.RemoveAt(index);
                return(true);
            }
            return(false);
        }
예제 #9
0
        /// <summary>
        /// Return node at given index.
        /// </summary>
        /// <param name="index">Index of node to return</param>
        /// <returns>Node at given index</returns>
        public ReadOnlyNode NodeAt(int index)
        {
            if (index < 0 || index >= Count)
            {
                throw new ArgumentOutOfRangeException("Index is out of range");
            }
            var node = frontNode;

            for (int i = 0; i < index && node != null; i++)
            {
                node = node.Next;
            }
            if (node == null)
            {
                throw new InvalidOperationException("Linked list is corrupted");
            }
            return(ReadOnlyNode.Create(node).Value);
        }
예제 #10
0
        private List <Edge> JarnikImpl()
        {
            PrepareForGraphTraverse();
            DijkstraImpl(nodes[0], EdgeRelaxJarnik);
            var spanningTree = new List <Edge>();

            foreach (var node in nodes)
            {
                if (node.PreviousNode == null)
                {
                    continue;
                }
                var from = ReadOnlyNode.Create(node.PreviousNode).Value;
                var to   = ReadOnlyNode.Create(node).Value;
                spanningTree.Add(new Edge(node.Distance, from, to));
            }
            return(spanningTree);
        }
예제 #11
0
 private void DFSRecursive(Node node, Node previousNode, Action <ReadOnlyNode> map)
 {
     if (node.Color == NodeColor.White)
     {
         node.PreviousNode = previousNode;
         node.Distance     = previousNode != null ? previousNode.Distance + 1 : 0;
     }
     // In case of cycle detection
     map?.Invoke(ReadOnlyNode.Create(node).Value);
     if (node.Color != NodeColor.White)
     {
         return;
     }
     node.Color = NodeColor.Gray;
     foreach (var edge in node.OutEdges)
     {
         DFSRecursive(edge.NodeTo.ThisNode as Node, node, map);
     }
     node.Color = NodeColor.Black;
 }
예제 #12
0
        /// <summary>
        /// Check whether graph contains a cycle (using DFS).
        /// </summary>
        /// <returns>True whether graph containst cycle, false otherwise</returns>
        public bool ContainsCycle()
        {
            PrepareForGraphTraverse();
            bool cycleDetected = false;

            foreach (var node in nodes)
            {
                if (node.Color == NodeColor.White)
                {
                    DFS(ReadOnlyNode.Create(node).Value, (readOnlyNode) => {
                        cycleDetected = (readOnlyNode.ThisNode as Node).Color == NodeColor.Gray;
                    });
                    if (cycleDetected)
                    {
                        break;
                    }
                }
            }
            ClearTraversingStats();
            return(cycleDetected);
        }
예제 #13
0
        /// <summary>
        /// Add element (key-value pair) to tree.
        /// </summary>
        /// <param name="key">Element's key</param>
        /// <param name="value">Element's value</param>
        /// <returns>Added node</returns>
        public ReadOnlyNode Add(TKey key, TValue value)
        {
            if (root == null) // Insert root
            {
                root  = new Node(key, value, null);
                Count = 1;
                return(Root.Value);
            }
            var result = FindNodeImpl(key);
            var node   = result.Node;

            if (node != null) // Key-Value already present, just overwrite current value
            {
                node.Value = value;
            }
            else
            {
                node = InsertNewNode(key, value, result.ParentNode);
            }
            return(ReadOnlyNode.Create(node).Value);
        }
예제 #14
0
 /// <summary>
 /// Return first node that match given predicate.
 /// </summary>
 /// <param name="predicate">Predicate</param>
 /// <returns>Node with value that match given predicate, otherwise null</returns>
 public ReadOnlyNode?Find(Predicate <T> predicate) => ReadOnlyNode.Create(FindFrom(predicate, frontNode));