-
Notifications
You must be signed in to change notification settings - Fork 238
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #256 from Mayur-nimkande-20/mayur
Add graphs basics folder
- Loading branch information
Showing
10 changed files
with
601 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
|
||
# Graph Data Structure Cheat Sheet | ||
|
||
## 1. What is a Graph? | ||
A **Graph** is a data structure consisting of a set of nodes (or vertices) and edges that connect these nodes. | ||
|
||
- **Vertices (V)**: Individual entities in the graph. | ||
- **Edges (E)**: Connections between two vertices. | ||
|
||
A graph is represented as **G(V, E)**, where: | ||
- **V** is a set of vertices | ||
- **E** is a set of edges | ||
|
||
### Types of Graphs: | ||
1. **Directed Graph (Digraph)**: Edges have direction (u → v). | ||
2. **Undirected Graph**: Edges are bidirectional (u ↔ v). | ||
3. **Weighted Graph**: Edges have weights or costs associated with them. | ||
4. **Unweighted Graph**: All edges have the same weight or no weight at all. | ||
|
||
### Common Terminologies: | ||
- **Adjacency**: Two vertices are adjacent if they are connected by an edge. | ||
- **Degree**: The number of edges connected to a vertex. | ||
- **Path**: A sequence of vertices where each adjacent pair is connected by an edge. | ||
- **Cycle**: A path where the first and last vertices are the same. | ||
|
||
## 2. Graph Representation | ||
|
||
### 2.1 Adjacency Matrix | ||
An `N x N` matrix is used to represent the graph where `N` is the number of vertices. | ||
- **adj[i][j] = 1** if there is an edge from vertex `i` to vertex `j`. | ||
- **adj[i][j] = 0** otherwise. | ||
|
||
### 2.2 Adjacency List | ||
Each vertex has a list of all vertices it is connected to. This representation is more space-efficient for sparse graphs. | ||
|
||
## 3. Graph Traversal | ||
|
||
### 3.1 Breadth-First Search (BFS) | ||
A level-order traversal technique that starts from a given node and visits all its neighbors, then proceeds to the neighbors' neighbors. | ||
|
||
### 3.2 Depth-First Search (DFS) | ||
DFS explores as far as possible along each branch before backtracking. | ||
|
||
## 4. Common Graph Algorithms | ||
|
||
### 4.1 Shortest Path Algorithms | ||
- **Dijkstra’s Algorithm**: Finds the shortest path from a single source to all other vertices (for non-negative weights). | ||
- **Bellman-Ford Algorithm**: Handles graphs with negative weights. | ||
- **Floyd-Warshall Algorithm**: Finds the shortest paths between all pairs of vertices. | ||
|
||
### 4.2 Minimum Spanning Tree Algorithms | ||
- **Prim’s Algorithm**: Greedy algorithm to find the MST, starting from any node. | ||
- **Kruskal’s Algorithm**: Uses union-find to select the shortest edges. | ||
|
||
### 4.3 Topological Sorting | ||
A linear ordering of vertices in a directed acyclic graph (DAG). | ||
|
||
### 4.4 Detecting Cycles | ||
- Use DFS to detect cycles in directed/undirected graphs. | ||
|
||
### 4.5 Strongly Connected Components (Kosaraju’s Algorithm) | ||
Decomposes a directed graph into strongly connected components. | ||
|
||
## 5. Frequently Asked Graph Problems | ||
|
||
### 5.1 Basic Graph Traversal | ||
- BFS of a graph | ||
- DFS of a graph | ||
- Connected Components | ||
|
||
### 5.2 Shortest Paths | ||
- Dijkstra’s Algorithm | ||
- Bellman-Ford Algorithm | ||
- Shortest Path in Binary Maze | ||
|
||
### 5.3 MST (Minimum Spanning Tree) | ||
- Prim's MST | ||
- Kruskal's MST | ||
|
||
### 5.4 Advanced Graph Problems | ||
- Topological Sort of a Directed Graph | ||
- Detect Cycle in Directed Graph | ||
- Strongly Connected Components | ||
|
||
## 6. Frequently Asked DSA Graph Questions | ||
|
||
1. **Breadth-First Search (BFS) and Depth-First Search (DFS)** | ||
- Implement BFS and DFS for a graph. | ||
- Find the number of connected components in an undirected graph. | ||
|
||
2. **Shortest Path Algorithms** | ||
- Find the shortest path in an unweighted graph (BFS). | ||
- Find the shortest path in a weighted graph (Dijkstra, Bellman-Ford). | ||
|
||
3. **Cycle Detection** | ||
- Detect a cycle in an undirected graph (DFS). | ||
- Detect a cycle in a directed graph (DFS with backtracking). | ||
|
||
4. **Topological Sort** | ||
- Find the topological order of vertices in a directed acyclic graph (Kahn's Algorithm or DFS-based approach). | ||
|
||
5. **Minimum Spanning Tree (MST)** | ||
- Implement Prim’s algorithm. | ||
- Implement Kruskal’s algorithm. | ||
|
||
6. **Strongly Connected Components** | ||
- Find all the strongly connected components (SCCs) in a directed graph (Kosaraju’s algorithm, Tarjan’s algorithm). | ||
|
||
7. **Graph Coloring** | ||
- Implement graph coloring using BFS/DFS. | ||
- Check if a graph is bipartite. | ||
|
||
8. **Miscellaneous** | ||
- Find the number of islands in a matrix (connected components problem). | ||
- Clone a graph (deep copy of a graph). | ||
|
||
## 7. Common Interview Questions | ||
1. **Leetcode 200:** Number of Islands | ||
2. **Leetcode 207:** Course Schedule (Topological Sort) | ||
3. **Leetcode 743:** Network Delay Time (Dijkstra) | ||
4. **Leetcode 785:** Is Graph Bipartite? | ||
5. **Leetcode 997:** Find the Town Judge | ||
6. **Leetcode 399:** Evaluate Division (Graph Representation of Equations) | ||
|
||
-- | ||
|
||
## Credits | ||
|
||
This cheat sheet was created by [Mayur Nimkande](https://github.com/Mayur-nimkande-20), whose contributions are greatly appreciated. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// ## Credits | ||
|
||
// This cheat sheet was created by [Mayur Nimkande](https://github.com/Mayur-nimkande-20), whose contributions are greatly appreciated. | ||
|
||
|
||
#include <iostream> | ||
#include <vector> | ||
|
||
using namespace std; | ||
|
||
const int INF = 1e9; // A large value representing infinity | ||
|
||
// Function to implement Bellman-Ford algorithm for finding the shortest path | ||
bool bellmanFord(int start, int V, vector<vector<int>>& edges, vector<int>& dist) { | ||
dist[start] = 0; // Distance to the start node is 0 | ||
|
||
// Relax edges repeatedly | ||
for (int i = 0; i < V - 1; i++) { | ||
for (auto edge : edges) { | ||
int u = edge[0]; // Starting node of the edge | ||
int v = edge[1]; // Ending node of the edge | ||
int weight = edge[2]; // Weight of the edge | ||
|
||
// If the current distance to u is not infinite | ||
if (dist[u] != INF && dist[u] + weight < dist[v]) { | ||
dist[v] = dist[u] + weight; // Update the distance to v | ||
} | ||
} | ||
} | ||
|
||
// Check for negative-weight cycles | ||
for (auto edge : edges) { | ||
int u = edge[0]; | ||
int v = edge[1]; | ||
int weight = edge[2]; | ||
|
||
// If we can still relax the edge, there is a negative cycle | ||
if (dist[u] != INF && dist[u] + weight < dist[v]) { | ||
return false; // Negative cycle found | ||
} | ||
} | ||
|
||
return true; // No negative cycles found | ||
} | ||
|
||
/* | ||
Explanation: | ||
- This function implements the Bellman-Ford algorithm to find the shortest paths from a starting node to all other nodes in a graph. | ||
- Unlike Dijkstra's, it can handle negative weights and detects negative cycles. | ||
- The algorithm relaxes all edges multiple times (V-1 times, where V is the number of vertices). | ||
- After relaxation, it checks for negative cycles by attempting to relax the edges one more time. | ||
- It returns a boolean indicating whether a negative cycle was detected. | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// ## Credits | ||
|
||
// This cheat sheet was created by [Mayur Nimkande](https://github.com/Mayur-nimkande-20), whose contributions are greatly appreciated. | ||
|
||
|
||
#include <iostream> | ||
#include <vector> | ||
#include <queue> | ||
|
||
using namespace std; | ||
|
||
// Function to perform Breadth-First Search (BFS) | ||
void bfs(int start, vector<vector<int>>& adj) { | ||
// Create a queue to hold nodes to visit | ||
queue<int> q; | ||
// Create a visited array to keep track of visited nodes | ||
vector<bool> visited(adj.size(), false); | ||
|
||
// Start the BFS from the 'start' node | ||
q.push(start); | ||
visited[start] = true; // Mark the start node as visited | ||
|
||
while (!q.empty()) { // While there are nodes to visit | ||
int node = q.front(); // Get the front node of the queue | ||
cout << node << " "; // Print the node (or process it) | ||
q.pop(); // Remove the node from the queue | ||
|
||
// Visit all the neighbors of the current node | ||
for (int neighbor : adj[node]) { | ||
if (!visited[neighbor]) { // If the neighbor hasn't been visited | ||
q.push(neighbor); // Add it to the queue for visiting | ||
visited[neighbor] = true; // Mark it as visited | ||
} | ||
} | ||
} | ||
} | ||
|
||
/* | ||
Explanation: | ||
- This function implements Breadth-First Search (BFS) on a graph. | ||
- It starts from a specified node (the 'start' node) and explores all of its neighboring nodes first. | ||
- It uses a queue to keep track of nodes that need to be visited, ensuring that nodes are processed in the order they are discovered. | ||
- A 'visited' array is used to mark nodes as visited to prevent re-visiting them, which would lead to an infinite loop. | ||
- The function prints out each node as it is visited. | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// ## Credits | ||
|
||
// This cheat sheet was created by [Mayur Nimkande](https://github.com/Mayur-nimkande-20), whose contributions are greatly appreciated. | ||
|
||
|
||
#include <iostream> | ||
#include <vector> | ||
|
||
using namespace std; | ||
|
||
// Utility function for DFS | ||
void dfsUtil(int node, vector<vector<int>>& adj, vector<bool>& visited) { | ||
visited[node] = true; // Mark the current node as visited | ||
cout << node << " "; // Print the node (or process it) | ||
|
||
// Visit all the neighbors of the current node | ||
for (int neighbor : adj[node]) { | ||
if (!visited[neighbor]) { // If the neighbor hasn't been visited | ||
dfsUtil(neighbor, adj, visited); // Recursively visit it | ||
} | ||
} | ||
} | ||
|
||
// Function to perform Depth-First Search (DFS) | ||
void dfs(int start, vector<vector<int>>& adj) { | ||
vector<bool> visited(adj.size(), false); // Keep track of visited nodes | ||
dfsUtil(start, adj, visited); // Start DFS from the 'start' node | ||
} | ||
|
||
/* | ||
Explanation: | ||
- This function performs Depth-First Search (DFS) on a graph. | ||
- DFS explores as far as possible along each branch before backtracking, creating a path-like exploration. | ||
- The 'dfsUtil' function is a utility that performs the actual recursion for exploring nodes. | ||
- Similar to BFS, a 'visited' array is used to keep track of which nodes have been visited, preventing cycles. | ||
- The function prints each node as it is visited. | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// ## Credits | ||
|
||
// This cheat sheet was created by [Mayur Nimkande](https://github.com/Mayur-nimkande-20), whose contributions are greatly appreciated. | ||
|
||
|
||
#include <iostream> | ||
#include <vector> | ||
#include <queue> | ||
|
||
using namespace std; | ||
|
||
const int INF = 1e9; // A large value representing infinity | ||
|
||
// Function to implement Dijkstra's algorithm for finding the shortest path | ||
vector<int> dijkstra(int start, vector<vector<pair<int, int>>>& graph) { | ||
int V = graph.size(); // Number of vertices | ||
vector<int> dist(V, INF); // Distance array, initialized to "infinity" | ||
dist[start] = 0; // Distance to the starting node is 0 | ||
|
||
// Min-heap (priority queue) to hold nodes and their distances | ||
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; | ||
pq.push({0, start}); // Start from the initial node | ||
|
||
while (!pq.empty()) { // While there are nodes to process | ||
int u = pq.top().second; // Get the node with the smallest distance | ||
pq.pop(); // Remove it from the queue | ||
|
||
// Explore neighbors of the current node | ||
for (auto& edge : graph[u]) { | ||
int v = edge.first; // The neighboring node | ||
int weight = edge.second; // The distance to the neighbor | ||
|
||
// If a shorter path to neighbor is found | ||
if (dist[u] + weight < dist[v]) { | ||
dist[v] = dist[u] + weight; // Update distance | ||
pq.push({dist[v], v}); // Add neighbor to the queue | ||
} | ||
} | ||
} | ||
|
||
return dist; // Return the distances from the start node | ||
} | ||
|
||
/* | ||
Explanation: | ||
- This function implements Dijkstra's algorithm to find the shortest path from a starting node to all other nodes in a weighted graph. | ||
- It uses a priority queue (min-heap) to process the next node with the smallest known distance. | ||
- The 'dist' array keeps track of the shortest distance from the start node to every other node. | ||
- The algorithm iteratively updates the distances to each neighboring node based on the current node's distance. | ||
- It returns an array of the shortest distances to all nodes from the start node. | ||
*/ |
Oops, something went wrong.