Algorithms_in_C++  1.0.0
Set of algorithms implemented in C++.
CycleCheck Class Reference

Static Public Member Functions

static bool isCyclicDFS (Graph const &graph)
 
static bool isCyclicBFS (Graph const &graph)
 

Private Types

enum  nodeStates : uint8_t { not_visited = 0, in_stack, visited }
 

Static Private Member Functions

static bool isCyclicDFSHelper (AdjList const &adjList, std::vector< nodeStates > *state, unsigned int node)
 

Member Function Documentation

◆ isCyclicBFS()

static bool CycleCheck::isCyclicBFS ( Graph const &  graph)
inlinestatic

Check if a graph has cycle or not.

This function uses BFS to check if a graph is cyclic or not.

Parameters
graphwhich needs to be evaluated for the presence of cycle.
Returns
true if a cycle is detected, else false.
241  {
242  AdjList graphAjdList = graph.getAdjList();
243 
244  std::vector<unsigned int> indegree(graph.getVertices(), 0);
245  // Calculate the indegree i.e. the number of incident edges to the node.
246  for (auto const& [parent, children] : graphAjdList) {
247  for (auto const& child : children) {
248  indegree[child]++;
249  }
250  }
251 
252  std::queue<unsigned int> can_be_solved;
253  for (auto node = 0; node < graph.getVertices(); node++) {
254  // If a node doesn't have any input edges, then that node will
255  // definately not result in a cycle and can be visited safely.
256  if (!indegree[node]) {
257  can_be_solved.emplace(node);
258  }
259  }
260 
261  // Vertices that need to be traversed.
262  auto remain = graph.getVertices();
263  // While there are safe nodes that we can visit.
264  while (!can_be_solved.empty()) {
265  auto front = can_be_solved.front();
266  // Visit the node.
267  can_be_solved.pop();
268  // Decrease number of nodes that need to be traversed.
269  remain--;
270 
271  // Visit all the children of the visited node.
272  if (auto it = graphAjdList.find(front); it != graphAjdList.end()) {
273  for (auto child : it->second) {
274  // Check if we can visited the node safely.
275  if (--indegree[child] == 0) {
276  // if node can be visited safely, then add that node to
277  // the visit queue.
278  can_be_solved.emplace(child);
279  }
280  }
281  }
282  }
283 
284  // If there are still nodes that we can't visit, then it means that
285  // there is a cycle and return true, else return false.
286  return !(remain == 0);
287  }
Here is the call graph for this function:

◆ isCyclicDFS()

static bool CycleCheck::isCyclicDFS ( Graph const &  graph)
inlinestatic

Driver function to check if a graph has a cycle.

This function uses DFS to check for cycle in the graph.

Parameters
graphwhich needs to be evaluated for the presence of cycle.
Returns
true if a cycle is detected, else false.

State of the node.

It is a vector of "nodeStates" which represents the state node is in. It can take only 3 values: "not_visited", "in_stack", and "visited".

Initially, all nodes are in "not_visited" state.

206  {
207  /** State of the node.
208  *
209  * It is a vector of "nodeStates" which represents the state node is in.
210  * It can take only 3 values: "not_visited", "in_stack", and "visited".
211  *
212  * Initially, all nodes are in "not_visited" state.
213  */
214  std::vector<nodeStates> state(graph.getVertices(), not_visited);
215 
216  // Start visiting each node.
217  for (auto node = 0; node < graph.getVertices(); node++) {
218  // If a node is not visited, only then check for presence of cycle.
219  // There is no need to check for presence of cycle for a visited
220  // node as it has already been checked for presence of cycle.
221  if (state[node] == not_visited) {
222  // Check for cycle.
223  if (isCyclicDFSHelper(graph.getAdjList(), &state, node)) {
224  return true;
225  }
226  }
227  }
228 
229  // All nodes have been safely traversed, that means there is no cycle in
230  // the graph. Return false.
231  return false;
232  }
Here is the call graph for this function:

◆ isCyclicDFSHelper()

static bool CycleCheck::isCyclicDFSHelper ( AdjList const &  adjList,
std::vector< nodeStates > *  state,
unsigned int  node 
)
inlinestaticprivate

Helper function of "isCyclicDFS".

Parameters
adjListis the adjacency list representation of some graph.
stateis the state of the nodes of the graph.
nodeis the node being evaluated.
Returns
true if graph has a cycle, else false.
167  {
168  // Add node "in_stack" state.
169  (*state)[node] = in_stack;
170 
171  // If the node has children, then recursively visit all children of the
172  // node.
173  if (auto const& it = adjList.find(node); it != adjList.end()) {
174  for (auto child : it->second) {
175  // If state of child node is "not_visited", evaluate that child
176  // for presence of cycle.
177  if (auto state_of_child = (*state)[child];
178  state_of_child == not_visited) {
179  if (isCyclicDFSHelper(adjList, state, child)) {
180  return true;
181  }
182  } else if (state_of_child == in_stack) {
183  // If child node was "in_stack", then that means that there
184  // is a cycle in the graph. Return true for presence of the
185  // cycle.
186  return true;
187  }
188  }
189  }
190 
191  // Current node has been evaluated for the presence of cycle and had no
192  // cycle. Mark current node as "visited".
193  (*state)[node] = visited;
194  // Return that current node didn't result in any cycles.
195  return false;
196  }
Here is the call graph for this function:

The documentation for this class was generated from the following file:
graph
Definition: bfs.cpp:3
std::vector< unsigned int >
std::queue::emplace
T emplace(T... args)
node
Definition: avltree.cpp:13
node
struct list node
std::queue
STL class.
std::queue::front
T front(T... args)
CycleCheck::isCyclicDFSHelper
static bool isCyclicDFSHelper(AdjList const &adjList, std::vector< nodeStates > *state, unsigned int node)
Definition: cycle_check_directed_graph.cpp:165
std::queue::pop
T pop(T... args)
std::queue::empty
T empty(T... args)
std::unordered_map< unsigned int, std::vector< unsigned int > >