diff --git a/Graph/BFS Traversal.md b/Graph/BFS Traversal.md index 707c369..c19c6c1 100644 --- a/Graph/BFS Traversal.md +++ b/Graph/BFS Traversal.md @@ -5,7 +5,18 @@ -> The nodes which are equidistant from parent node are said to be in level-1 and likewise. -> First print elements in level-0, then level-1 and so on. -Code: (For Undirected Graph) +## Approach + +-> We need to have this before proceeding : + +1) Queue Data structure +2) Visited Array – An array with all values initialised with 0. + +-> We will push the 1st node into the queue data structure and mark it as visited. After this, we will find its adjacent nodes. If we get some unvisited node, we will simply push this adjacent node into the queue data structure + +-> Now since the work of the 1st node is done, we will pop out this node from the queue. Now, this process goes on until the queue is not empty. + +## Code: (For Undirected Graph) ```cpp // Assuming inputs are taken in adjacency list vector adj[n+1]; @@ -33,4 +44,12 @@ while(!q.empty()){ return bfs; ``` -### Complexities: \ No newline at end of file +## Complexities + +-> Time Complexity : O(N + E) + +N = Nodes , E = travelling through adjacent nodes + +-> Space Complexity : O(N + E) + O(N) + O(N) + +Space for adjacency list, visited array, queue data structure \ No newline at end of file diff --git a/Graph/DFS Traversal.md b/Graph/DFS Traversal.md index ae2e8f4..994c002 100644 --- a/Graph/DFS Traversal.md +++ b/Graph/DFS Traversal.md @@ -1,26 +1,45 @@ ## DFS (Depth first search) traversal technique --> +-> Depth First Traversal is a traversal technique/algorithm, used to traverse through all the nodes in the given graph. +-> It starts traversal through any one of its neighbour nodes and explores the farthest possible node in each path/branch and then starts Back-tracking. -Code: +## Approach + +1) Start with a random node from graph +2) Make an array to keep track of visited nodes, once visited make that node as visited +3) Print this current node +4) Get neighbour nodes and perform above steps recursively for each node deeply/depthly if node is unvisited. + + +## Code ```cpp -void dfst(int node, vectoradj[], vector &v, vector &dfs){ - v[node]=1; +void dfst(int node, vectoradj[], vector &vis, vector &dfs){ + vis[node]=1; dfs.push_back(node); for(auto it : adj[node]){ - if(!v[it]){ - dfst(it, adj, v, dfs); + if(!vis[it]){ + dfst(it, adj, vis, dfs); } } } vector dfsOfGraph(int V, vector adj[]){ - vector v (V,0); + vector vis(V,0); vector dfs; int sn = 0; // starting node - dfst(sn, adj, v, dfs); + dfst(sn, adj, vis, dfs); return dfs; } -``` \ No newline at end of file +``` + +## Complexities + +-> Time complexity: O(N + E) + + Where N is the time taken for visiting N nodes and E is for travelling through adjacent nodes. + +-> Space Complexity: O(N + E) + O(N) + O(N) + + Space for adjacency list, Array, Auxiliary space. diff --git a/Graph/Dijkstra's Algorithm.md b/Graph/Dijkstra's Algorithm.md new file mode 100644 index 0000000..93ca97f --- /dev/null +++ b/Graph/Dijkstra's Algorithm.md @@ -0,0 +1,63 @@ +# Dijkstra's Algorithm for Shortest Distance + +## Example Problem Statement + +Given a weighted, undirected, and connected graph of V vertices and E edges, Find the shortest distance of all the vertex’s from the source vertex S. + +**NOTE** : Graph doesn't contain any negative weighted cycle. + +## Approach + +-> We can implement this algorithm using the following steps: + +1) We will be using a min-heap and a distance array of size N initialized with infinity (indicating that at present none of the nodes are reachable from the source node) and initialize the distance to source node as 0. + +2) We will push the source node into the queue. + +3) For every node at the top of the queue we pop that element out and look for its adjacent nodes. If the current reachable distance is better than the previous distance indicated by the distance array, we update the distance and push it in the queue. + +4) A node with a lesser distance will be at the top of the priority queue as opposed to a node with a higher distance. + +By following the steps 3, until our queue becomes empty, we would get the minimum distance from the source node to all other nodes. + +## Code + +```cpp +// assuming 1 based indexing of graph and input are taken in graph. +vector > g[n+1]; + +// Dijkstra's algorithm begins from here +priority_queue,vector >,greater>> pq; + +// 1-indexed array for calculating shortest paths +vector distTo(n+1,INT_MAX); +distTo[source] = 0; + +// (dist,source) +pq.push(make_pair(0,source)); + +while( !pq.empty() ){ + int dist = pq.top().first; + int prev = pq.top().second; + pq.pop(); + + vector >::iterator it; + for( it = g[prev].begin(); it != g[prev].end(); it++ ){ + int next = it -> first; + int nextDist = it -> second; + if( distTo[next] > distTo[prev] + nextDist){ + distTo[next] = distTo[prev] + nextDist; + pq.push(make_pair(distTo[next], next)); + } + } +} +``` +## Complexities + +-> Time Complexity: O( (N + E) * logN). + +Going through N nodes and E edges and log N for priority queue + +-> Space Complexity: O(N). + +Distance array and priority queue \ No newline at end of file diff --git a/Graph/Topological Sort.md b/Graph/Topological Sort.md new file mode 100644 index 0000000..5b1faed --- /dev/null +++ b/Graph/Topological Sort.md @@ -0,0 +1,72 @@ +# Topological Sort + +Definition : The linear ordering of nodes/vertices such that if there exists an edge between 2 nodes u,v then ‘u’ appears before ‘v’. + +## Example Problem Statement + +Given a graph, find the topological order for the given graph. + +**NOTE** : Topological Sort can only be possible for DAG ( Directed acyclic graph) and if there is a cycle then topological order will not be possible. + +## Approach + +-> We can implement this algorithm using the following steps: + +1) In order to maintain the In-degree of each and every node, we take an array of size v( where v is the number of nodes). + +2) Find in-degree of all nodes and fill them in an array + +3) Now we will take Queue data structure and add nodes that have in-degree is 0 ( because we have to start this question from a node that doesn’t have any previous edges), and simply apply bfs on queue with some conditions. + +4) Take the top/peek node from Queue ( let the popped node be z), add this z to our answer. (If you can observe clearly the above step is nothing but Normal BFS traversal). + + Now we have to apply some conditions to the BFS : + + 1) Take neighbour nodes of popped nodes and reduce their in-degree by 1. + 2) Now check if in-degree of the popped element becomes 0 then add this neighbour element into the queue. + +5) Repeat step 4 till the queue becomes empty. + +## Code + +```cpp +vector topo(int N, vector adj[]) { + // Adjacency List will be given in question or you can make your own. + queue q; + vector indegree(N, 0); + for( int i = 0; i < N; i++ ) { + for(auto it: adj[i]) { + indegree[it]++; + } + } + + for( int i = 0; i < N; i++ ) { + if(indegree[i] == 0) { + q.push(i); + } + } + // Made vector topo to store the topological sort order. + vector topo; + while( !q.empty() ) { + int node = q.front(); + q.pop(); + topo.push_back(node); + for(auto it : adj[node]) { + indegree[it]--; + if( indegree[it] == 0 ) { + q.push(it); + } + } + } + return topo; +} +``` +## Complexities + +-> Time Complexity: O( N + E ). + +Going through N nodes and E edges. + +-> Space Complexity: O(N) + O(N). + +For Queue and Array. \ No newline at end of file