// Perform a depth first search on a graph with n nodes. // This impl returns number of connected nodes starting from firstNode public static int DFS(T[] nodes, Common.Edge <T, W>[] dependencies, T firstNode) { // Example // nodes = { a, b, c, d, e, f } // dependencies = { {a, d}, {f, b}, {b, d}, {f, a}, {d, c}} // DFS(params, a).Count == 5 // connected to 5 other nodes // DFS(params, e).Count == 1 // not connected to any other nodes var graph = new Common.Graph <T, W>(); for (int i = 0; i < dependencies.Length; i++) { graph.AddDirectedEdge(dependencies[i]); } var numberOfNodes = nodes.Length; // initialize visited list/map var visited = new Dictionary <T, bool>(); foreach (var p in nodes) { visited[p] = false; } var count = 0; // non recursive solution, here we use Stack var stack = new pv.Common.Stack <T>(); // lets use homemade stack stack.Push(firstNode); visited[firstNode] = true; while (!stack.IsEmpty()) { var node = stack.Pop(); // famous doSomething :) e.g. count++ count++; if (graph.ContainsKey(node)) { foreach (var edge in graph[node]) { if (!visited[edge.To]) { stack.Push(edge.To); visited[edge.To] = true; } } } } return(count); }
public static bool IsRouteBetweenNodes(T[] nodes, Graph <T, W> graph, T node1, T node2) { // we can use both DFS or BFS // try DFS first //first case if (node1.CompareTo(node2) == 0) { return(true); } // we need list of visited nodes var visited = new Dictionary <T, bool>(); // init visited map foreach (var node in nodes) { visited[node] = false; } // we need a stack here var stack = new pv.Common.Stack <T>(); stack.Push(node1); visited[node1] = true; while (!stack.IsEmpty()) { var node = stack.Pop(); if (graph.ContainsKey(node)) { foreach (var ne in graph[node]) { if (!visited[ne.To]) { if (ne.To.CompareTo(node2) == 0) { return(true); } stack.Push(ne.To); visited[ne.To] = true; } } } } return(false); }
// wil try to make solution without recursion public static int[] GetBuildOrder(int[] projects, int[,] dependencies) { var graph = new Dictionary <int, List <int> >(); var numberOfPairs = dependencies.GetUpperBound(0) + 1; var orderedProjects = new int[projects.Length]; var orderedProjectsIndex = projects.Length - 1; for (int i = 0; i < numberOfPairs; i++) { if (!graph.ContainsKey(dependencies[i, 0])) { graph[dependencies[i, 0]] = new List <int>(); } graph[dependencies[i, 0]].Add(dependencies[i, 1]); // storing indexes of projects } // lets try with DFS // we need list of visited nodes var visited = new bool[projects.Length]; // by default all are false var stack = new pv.Common.Stack <int>(); // start from node 0, try to find nodes which are not dependent on any other nodes for (int at = 0; at < projects.Length; at++) { if (!visited[at]) { stack.Push(at); // push index of a project to stack visited[at] = true; var visitedNodes = new List <int>(); // for particular project on index at while (!stack.IsEmpty()) { var projectIndex = stack.Pop(); // then traverse to its connections and mark visited if (graph.ContainsKey(projectIndex)) { for (int j = 0; j < graph[projectIndex].Count; j++) { if (!visited[graph[projectIndex][j]]) { stack.Push(graph[projectIndex][j]); visited[graph[projectIndex][j]] = true; } } } visitedNodes.Add(projectIndex); } // insert visitedNodes to orderedProjects for (int k = visitedNodes.Count - 1; k >= 0; k--) { orderedProjects[orderedProjectsIndex] = visitedNodes[k]; orderedProjectsIndex--; } } } return(orderedProjects); }