Google Interview Question
Developer Program EngineersYou can do it via modified DFS - but instead of visited nodes set use current path set - whenever recursing into a next node add it to the path and remove it on the way back. If you find next node in current path - it's a cycle.
bool cycleExists(const Graph::Node &start,
const Graph::Node ¤tNode,
std::set<Graph::Node> &pathNodes) {
pathNodes.insert(currentNode);
for(auto it = currentNode.adjucents.begin(); it != currentNode.adjucents.end(); ++it) {
if(pathNodes.find(*it) == pathNodes.end()) {
if(cycleExists(start, *it, pathNodes)) return true;
pathNodes.erase(*it);
} else {
return true;
}
}
return false;
}
bool cycleExists(const Graph::Node &start) {
std::set<Graph::Node> pathNodes;
return cycleExists(start, start, pathNodes);
}
this is what i got from wiki, which is said above...
L ← Empty list that will contain the sorted elements
S ← Set of all nodes with no incoming edges
while S is non-empty do
remove a node n from S
insert n into L
for each node m with an edge e from n to m do
remove edge e from the graph
if m has no other incoming edges then
insert m into S
if graph has edges then
output error message (graph has at least one cycle)
else
output message (proposed topologically sorted order: L)
The cycle detection algorithm for trees can easily be modified to work for graphs. The key is that in a
DFS of an acyclic graph, a node whose descendants have all been visited can be seen again without implying
a cycle. However, if a node is seen a second time before all of its descendants have been visited, then there
must be a cycle. Can you see why this is? Suppose there is a cycle containing node A. Then this means
that A must be reachable from one of its descendants. So when the DFS is visiting that descendant, it will
see A again, before it has finished visiting all of A’s descendants. So there is a cycle.
In order to detect cycles, we use a modified depth first search called a colored DFS. All nodes are initially
marked white. When a node is encountered, it is marked grey, and when its descendants are completely
visited, it is marked black. If a grey node is ever encountered, then there is a cycle.
By doing a BFS or DFS and keeping track of the visited nodes we can detect a cycle. A cycle is detected when we visit an already visited node during the traversal.
keeping track of only visited will not work. lets say that you have levels in graph.
A-- ----B
|
C
so A & B directs to C, so only visited will say that there is a cycle but its not. We can keep track of incoming and outgoing time stamp and check if incoming TS already exists and is < current TS. it should be simple to do this while doing DFS/BFS
For DFS, if the graph is huge, and the edge to form the cycle is really deep. you might run out of stack.
Also for BFS, you need to store at least one layer of nodes, which could be exponential in the worst case. If so, you have the risk to run out of memory.
topological sorting
- syrus January 07, 2011find indgree = 0 nodes and put them in a queue Q
get a node N each time out of the Q, and process N; decrease the indegree of the nodes point to by 1; if a node N points to now has indegree of 0, then put it in Q
so on and so forth until there is nothing left in Q; if all nodes are processed, then G has no cycle