Algorithms_in_C++  1.0.0
Set of algorithms implemented in C++.
depth_first_search_with_stack.cpp File Reference

Depth First Search Algorithm using Stack (Depth First Search Algorithm) More...

#include <iostream>
#include <stack>
#include <vector>
#include <cassert>
#include <limits>
Include dependency graph for depth_first_search_with_stack.cpp:

Namespaces

 graph
 Graph Algorithms.
 
 

Functions

void graph::depth_first_search::addEdge (std::vector< std::vector< size_t >> *adj, size_t u, size_t v)
 Adds and edge between two vertices of graph say u and v in this case. More...
 
std::vector< size_t > graph::depth_first_search::dfs (const std::vector< std::vector< size_t > > &graph, size_t start)
 Explores the given vertex, exploring a vertex means traversing over all the vertices which are connected to the vertex that is currently being explored and push it onto the stack. More...
 
static void tests ()
 
int main ()
 Main function. More...
 

Variables

constexpr int WHITE = 0
 
constexpr int GREY = 1
 indicates the node hasn't been explored
 
constexpr int BLACK = 2
 indicates node is in stack waiting to be explored
 
constexpr int64_t INF = std::numeric_limits<int16_t>::max()
 indicates node has already been explored
 

Detailed Description

Depth First Search Algorithm using Stack (Depth First Search Algorithm)

Author
Ayaan Khan
Saurav Uppoor

Depth First Search also quoted as DFS is a Graph Traversal Algorithm. Time Complexity O(|V| + |E|) where V is number of vertices and E is number of edges in graph.

Application of Depth First Search are

  1. Finding connected components
  2. Finding 2-(edge or vertex)-connected components.
  3. Finding 3-(edge or vertex)-connected components.
  4. Finding the bridges of a graph.
  5. Generating words in order to plot the limit set of a group.
  6. Finding strongly connected components.

Working

  1. Mark all vertices as unvisited (colour it WHITE).
  2. Push starting vertex into the stack and colour it GREY.
  3. Once a node is popped out of the stack and is coloured GREY, we colour it BLACK.
  4. Push all its neighbours which are not coloured BLACK.
  5. Repeat steps 4 and 5 until the stack is empty.

Function Documentation

◆ addEdge()

void graph::depth_first_search::addEdge ( std::vector< std::vector< size_t >> *  adj,
size_t  u,
size_t  v 
)

Adds and edge between two vertices of graph say u and v in this case.

Parameters
adjAdjacency list representation of graph
ufirst vertex
vsecond vertex
64  {
65  /*
66  *
67  * Here we are considering undirected graph that's the
68  * reason we are adding v to the adjacency list representation of u
69  * and also adding u to the adjacency list representation of v
70  *
71  */
72  (*adj)[u - 1].push_back(v - 1);
73 }

◆ dfs()

std::vector<size_t> graph::depth_first_search::dfs ( const std::vector< std::vector< size_t > > &  graph,
size_t  start 
)

Explores the given vertex, exploring a vertex means traversing over all the vertices which are connected to the vertex that is currently being explored and push it onto the stack.

Parameters
adjgraph
startstarting vertex for DFS
Returns
vector with nodes stored in the order of DFS traversal

checked[i] stores the status of each node

while stack is not empty we keep exploring the node on top of stack

push the node to the final result vector

exploring the neighbours of the current node

Node has been explored

87  {
88  /// checked[i] stores the status of each node
89  std::vector<size_t> checked(graph.size(), WHITE), traversed_path;
90 
91  checked[start] = GREY;
93  stack.push(start);
94 
95  /// while stack is not empty we keep exploring the node on top of stack
96  while (!stack.empty()) {
97  int act = stack.top();
98  stack.pop();
99 
100  if (checked[act] == GREY) {
101  /// push the node to the final result vector
102  traversed_path.push_back(act + 1);
103 
104  /// exploring the neighbours of the current node
105  for (auto it : graph[act]) {
106  stack.push(it);
107  if (checked[it] != BLACK) {
108  checked[it] = GREY;
109  }
110  }
111  checked[act] = BLACK; /// Node has been explored
112  }
113  }
114  return traversed_path;
115 }
Definition: stack.h:26
Type top()
Definition: stack.h:93
void push(Type item)
Definition: stack.h:83
void pop()
Definition: stack.h:99
constexpr int GREY
indicates the node hasn't been explored
Definition: depth_first_search_with_stack.cpp:39
constexpr int BLACK
indicates node is in stack waiting to be explored
Definition: depth_first_search_with_stack.cpp:40
constexpr int WHITE
Definition: depth_first_search_with_stack.cpp:38
Graph Algorithms.
char stack[MAX]
Definition: paranthesis_matching.cpp:20
T push_back(T... args)
Here is the call graph for this function:

◆ main()

int main ( void  )

Main function.

Returns
0 on exit

creating a graph

taking input for the edges

taking input for the starting position

Printing the order of traversal

173  {
174  tests(); // execute the tests
175 
176  size_t vertices = 0, edges = 0, start_pos = 1;
177  std::vector<size_t> traversal;
178 
179  std::cout << "Enter the Vertices : ";
180  std::cin >> vertices;
181  std::cout << "Enter the Edges : ";
182  std::cin >> edges;
183 
184  /// creating a graph
186 
187  /// taking input for the edges
188  std::cout << "Enter the vertices which have edges between them : " << std::endl;
189  while (edges--) {
190  size_t u = 0, v = 0;
191  std::cin >> u >> v;
193  }
194 
195  /// taking input for the starting position
196  std::cout << "Enter the starting vertex [1,n]: " << std::endl;
197  std::cin >> start_pos;
198  start_pos -= 1;
199  traversal = graph::depth_first_search::dfs(adj, start_pos);
200 
201  /// Printing the order of traversal
202  for (auto x : traversal) {
203  std::cout << x << ' ';
204  }
205 
206  return 0;
207 }
static void tests()
Definition: depth_first_search_with_stack.cpp:123
void addEdge(std::vector< std::vector< size_t >> *adj, size_t u, size_t v)
Adds and edge between two vertices of graph say u and v in this case.
Definition: depth_first_search_with_stack.cpp:64
std::vector< size_t > dfs(const std::vector< std::vector< size_t > > &graph, size_t start)
Explores the given vertex, exploring a vertex means traversing over all the vertices which are connec...
Definition: depth_first_search_with_stack.cpp:87
T endl(T... args)
Here is the call graph for this function:

◆ tests()

static void tests ( )
static

Self-test implementations

Returns
none

Test 1

for the above sample data, this is the expected output

Test 2

for the above sample data, this is the expected output

Test 3

for the above sample data, this is the expected output

123  {
124  size_t start_pos;
125 
126  /// Test 1
127  std::cout << "Case 1: " << std::endl;
128  start_pos = 1;
130 
134 
135  std::vector<size_t> expected1 {1, 2, 3}; /// for the above sample data, this is the expected output
136  assert(graph::depth_first_search::dfs(g1, start_pos - 1) == expected1);
137  std::cout << "Passed" << std::endl;
138 
139  /// Test 2
140  std::cout << "Case 2: " << std::endl;
141  start_pos = 1;
143 
148 
149  std::vector<size_t> expected2 {1, 3, 2, 4}; /// for the above sample data, this is the expected output
150  assert(graph::depth_first_search::dfs(g2, start_pos - 1) == expected2);
151  std::cout << "Passed" << std::endl;
152 
153  /// Test 3
154  std::cout << "Case 3: " << std::endl;
155  start_pos = 2;
157 
162 
163  std::vector<size_t> expected3 {2, 4, 1, 3}; /// for the above sample data, this is the expected output
164  assert(graph::depth_first_search::dfs(g3, start_pos - 1) == expected3);
165  std::cout << "Passed" << std::endl;
166 
167 }
Here is the call graph for this function:

Variable Documentation

◆ WHITE

constexpr int WHITE = 0
constexpr

for IO operations header for std::stack header for std::vector header for preprocessor macro assert() header for limits of integral types