A graph is a collection of nodes (also called vertices) and edges that connect pairs of nodes. It is a more general structure than trees because it can have cycles and allow for multiple connections between nodes. Graphs are used to represent various real-world problems like social networks, web pages, transportation systems, etc.
There are two main ways to represent a graph in memory:
(i, j) represents whether there is an edge between vertex i and vertex j.In this example, we will implement a graph using an adjacency list. The graph will be undirected and unweighted.
#include <iostream>
#include <list>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
// Graph class
class Graph {
private:
int V; // Number of vertices
vector<list<int>> adj; // Adjacency list
public:
// Constructor to initialize graph with given number of vertices
Graph(int vertices) {
V = vertices;
adj.resize(V);
}
// Add an edge to the graph (undirected graph)
void addEdge(int u, int v) {
adj[u].push_back(v);
adj[v].push_back(u); // Since the graph is undirected
}
// Depth First Search (DFS)
void DFS(int start) {
vector<bool> visited(V, false);
stack<int> s;
s.push(start);
while (!s.empty()) {
int node = s.top();
s.pop();
if (!visited[node]) {
visited[node] = true;
cout << node << " ";
}
// Traverse all the adjacent vertices
for (int neighbor : adj[node]) {
if (!visited[neighbor]) {
s.push(neighbor);
}
}
}
cout << endl;
}
// Breadth First Search (BFS)
void BFS(int start) {
vector<bool> visited(V, false);
queue<int> q;
q.push(start);
visited[start] = true;
while (!q.empty()) {
int node = q.front();
q.pop();
cout << node << " ";
// Visit all unvisited adjacent vertices
for (int neighbor : adj[node]) {
if (!visited[neighbor]) {
visited[neighbor] = true;
q.push(neighbor);
}
}
}
cout << endl;
}
// Print the adjacency list
void printGraph() {
for (int i = 0; i < V; ++i) {
cout << i << ": ";
for (int neighbor : adj[i]) {
cout << neighbor << " ";
}
cout << endl;
}
}
};
int main() {
// Create a graph with 5 vertices
Graph g(5);
// Add edges to the graph
g.addEdge(0, 1);
g.addEdge(0, 4);
g.addEdge(1, 2);
g.addEdge(1, 3);
g.addEdge(1, 4);
g.addEdge(3, 4);
// Print the adjacency list of the graph
cout << "Adjacency List of the Graph:" << endl;
g.printGraph();
// Perform DFS starting from vertex 0
cout << "DFS starting from vertex 0: ";
g.DFS(0); // Output: 0 1 2 3 4
// Perform BFS starting from vertex 0
cout << "BFS starting from vertex 0: ";
g.BFS(0); // Output: 0 1 4 2 3
return 0;
}
Graph Constructor: Initializes a graph with V vertices and creates an adjacency list (adj), which is a vector of lists. Each list holds the neighbors of the corresponding vertex.
addEdge(): Adds an edge between two vertices u and v. Since it's an undirected graph, it adds both v to the adjacency list of u and u to the adjacency list of v.
DFS (Depth First Search):
start vertex, marks it as visited, and then explores all its neighbors.BFS (Breadth First Search):
start vertex, marks it as visited, and explores all its neighbors in breadth.printGraph(): Displays the adjacency list of the graph.
Adjacency List of the Graph:
0: 1 4
1: 0 2 3 4
2: 1
3: 1 4
4: 0 1 3
DFS starting from vertex 0: 0 1 2 3 4
BFS starting from vertex 0: 0 1 4 2 3
In this representation, a 2D array (matrix) is used to represent the graph. The element at position (i, j) in the matrix is 1 if there is an edge between vertex i and vertex j, otherwise it's 0.
#include <iostream>
using namespace std;
class Graph {
private:
int V; // Number of vertices
int** adjMatrix; // Adjacency matrix
public:
// Constructor to initialize the graph
Graph(int vertices) {
V = vertices;
adjMatrix = new int*[V];
for (int i = 0; i < V; i++) {
adjMatrix[i] = new int[V];
for (int j = 0; j < V; j++) {
adjMatrix[i][j] = 0; // Initialize all edges to 0
}
}
}
// Add an edge to the graph (undirected graph)
void addEdge(int u, int v) {
adjMatrix[u][v] = 1;
adjMatrix[v][u] = 1; // Since the graph is undirected
}
// Print the adjacency matrix
void printGraph() {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
cout << adjMatrix[i][j] << " ";
}
cout << endl;
}
}
// Destructor to clean up dynamically allocated memory
~Graph() {
for (int i = 0; i < V; i++) {
delete[] adjMatrix[i];
}
delete[] adjMatrix;
}
};
int main() {
// Create a graph with 4 vertices
Graph g(4);
// Add edges to the graph
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 3);
// Print the adjacency matrix
cout << "Adjacency Matrix of the Graph:" << endl;
g.printGraph();
return 0;
}
Adjacency Matrix of the Graph:
0 1 1 0
1 0 1 0
1 1 0 1
0 0 1 0
Graphs are a powerful data structure for modeling
Open this section to load past papers