EXPERIMENT – 4
AIM :- To Implement Minimum Spanning Tree using Prim and Kruskal.
CODE :-
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
#define V 5
struct Edge {
int src, dest, weight;
Edge(int s, int d, int w) : src(s), dest(d), weight(w) {}
};
struct DisjointSets {
vector<int> parent, rank;
DisjointSets(int n) {
parent.resize(n);
rank.resize(n, 0);
for (int i = 0; i < n; i++)
parent[i] = i;
}
int find(int u) {
if (parent[u] != u)
parent[u] = find(parent[u]);
return parent[u];
}
void merge(int x, int y) {
x = find(x);
y = find(y);
if (rank[x] > rank[y])
parent[y] = x;
else if (rank[x] < rank[y])
parent[x] = y;
else {
parent[y] = x;
rank[x]++;
}
}
};
int minKey(vector<int>& key, vector<bool>& mstSet) {
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++) {
if (!mstSet[v] && key[v] < min) {
min = key[v];
min_index = v;
}
}
return min_index;
}
void primMST(int graph[V][V]) {
vector<int> parent(V);
vector<int> key(V, INT_MAX);
vector<bool> mstSet(V, false);
key[0] = 0; // Start from the first vertex
parent[0] = -1; // First node is always the root of the MST
for (int count = 0; count < V - 1; count++) {
int u = minKey(key, mstSet);
mstSet[u] = true;
for (int v = 0; v < V; v++) {
if (graph[u][v] && !mstSet[v] && graph[u][v] < key[v]) {
parent[v] = u;
key[v] = graph[u][v];
}
}
}
cout << "\n--- Prim's Minimum Spanning Tree ---\n";
cout << "Edge\t\tWeight\n";
int totalWeight = 0;
for (int i = 1; i < V; i++) {
totalWeight += graph[i][parent[i]];
cout << parent[i] << " - " << i << "\t\t" << graph[i][parent[i]] << "\n";
}
cout << "Total Weight of Prim's MST: " << totalWeight << endl;
}
void kruskalMST(int graph[V][V]) {
vector<Edge> edges;
for (int i = 0; i < V; i++) {
for (int j = i + 1; j < V; j++) {
if (graph[i][j] != 0) {
edges.push_back(Edge(i, j, graph[i][j]));
}
}
}
sort(edges.begin(), edges.end(), [](Edge a, Edge b) { return a.weight < b.weight; });
DisjointSets ds(V);
vector<Edge> result;
for (Edge edge : edges) {
int set_u = ds.find(edge.src);
int set_v = ds.find(edge.dest);
if (set_u != set_v) {
result.push_back(edge);
ds.merge(set_u, set_v);
}
}
cout << "\n--- Kruskal's Minimum Spanning Tree ---\n";
cout << "Edge\t\tWeight\n";
int totalWeight = 0;
for (Edge edge : result) {
totalWeight += edge.weight;
cout << edge.src << " - " << edge.dest << "\t\t" << edge.weight << "\n";
}
cout << "Total Weight of Kruskal's MST: " << totalWeight << endl;
}
int main() {
int graph[V][V] = {
{0, 2, 0, 6, 0},
{2, 0, 3, 8, 5},
{0, 3, 0, 0, 7},
{6, 8, 0, 0, 9},
{0, 5, 7, 9, 0}
};
primMST(graph);
kruskalMST(graph);
return 0;
}
OUTPUT :-
-> PRIM'S ALGORITHM:
1.) Time Complexity:
• Using Matrix (current implementation): O(V²)
• Using Min-Heap (optimized version): O(E log V)
2.) Space Complexity: O(V²)
-> KRUSKAL'S ALGORITHM:
1.) Time Complexity: O(E log E) or O(E log V)
2.) Space Complexity: O(E + V)
Where: V = number of vertices E = number of edges
EXPERIMENT – 5
AIM :- To Implement Djikstra algorithm and analyse its time complexity
CODE :-
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
#define V 5
int minDistance(const vector<int>& dist, const vector<bool>& sptSet) {
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++) {
if (!sptSet[v] && dist[v] <= min) {
min = dist[v];
min_index = v;
}
}
return min_index;
}
void dijkstra(int graph[V][V], int src) {
vector<int> dist(V, INT_MAX);
vector<bool> sptSet(V, false);
dist[src] = 0;
for (int count = 0; count < V - 1; count++) {
int u = minDistance(dist, sptSet);
sptSet[u] = true; // Mark the picked vertex as processed
for (int v = 0; v < V; v++) {
if (!sptSet[v] && graph[u][v] &&
dist[u] != INT_MAX &&
dist[u] + graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
}
}
}
cout << "\n--- Dijkstra's Shortest Path ---\n";
cout << "Vertex\tDistance from Source (" << src << ")\n";
cout << " \n";
for (int i = 0; i < V; i++) {
cout << i << "\t" << (dist[i] == INT_MAX ? "INF" : to_string(dist[i])) << "\n";
}
cout << " \n";
}
int main() {
int graph[V][V] = {
{0, 4, 0, 0, 0},
{4, 0, 8, 0, 0},
{0, 8, 0, 7, 0},
{0, 0, 7, 0, 9},
{0, 0, 0, 9, 0}
};
dijkstra(graph, 0);
return 0;
}
OUTPUT :-
-> DJIKSTRA ALGORITHM:
1.) Time Complexity:
• Using Matrix (current implementation): O(V²)
• Using Min-Heap (optimized version): O(E log V)
2.) Space Complexity: O(V²)
Where: V = number of vertices E = number of edges
EXPERIMENT :- 6
AIM :- To Implement Bellman Ford algorithm and analyse its time complexity
CODE :-
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
#define V 6
void bellmanFord(int graph[V][V], int src) {
vector<int> dist(V, INT_MAX);
dist[src] = 0;
vector<pair<pair<int,int>, int>> edges;
for(int i = 0; i < V; i++) {
for(int j = 0; j < V; j++) {
if(graph[i][j] != 0) {
edges.push_back({{i,j}, graph[i][j]});
}
}
}
for(int i = 1; i < V; i++) {
for(auto edge : edges) {
int u = edge.first.first;
int v = edge.first.second;
int weight = edge.second;
if(dist[u] != INT_MAX && dist[u] + weight < dist[v]) {
dist[v] = dist[u] + weight;
}
}
}
for(auto edge : edges) {
int u = edge.first.first;
int v = edge.first.second;
int weight = edge.second;
if(dist[u] != INT_MAX && dist[u] + weight < dist[v]) {
cout << "Warning: Graph contains a negative weight cycle!\n";
return;
}
}
cout << "\n--- Bellman-Ford Algorithm Results ---\n";
cout << "From Source Vertex: " << src << "\n";
cout << " \n";
cout << "Vertex\tDistance from Source\n";
cout << " \n";
for(int i = 0; i < V; i++) {
cout << i << "\t" << (dist[i] == INT_MAX ? "INF" : to_string(dist[i])) << "\n";
}
cout << " \n";
}
int main() {
int graph[V][V] = {
{0, 4, -2, 0, 0, 0},
{0, 0, 3, 2, 3, 0},
{0, 0, 0, 0, -5, 0},
{0, 1, 0, 0, 0, 2},
{0, 0, 0, -3, 0, 0},
{0, 0, 0, 0, 0, 0}
};
cout << "Graph Representation:\n";
cout << "Edge\tWeight\n";
cout << " \n";
for(int i = 0; i < V; i++) {
for(int j = 0; j < V; j++) {
if(graph[i][j] != 0) {
cout << i << " -> " << j << "\t" << graph[i][j] << "\n";
}
}
}
cout << " \n";
bellmanFord(graph, 0);
return 0;
}
OUTPUT :-
-> BELLMAN FORD ALGORITHM:
1.) Time Complexity: O(VE)
2.) Space Complexity: O(V)
Where: V = number of vertices E = number of edges
EXPERIMENT – 7
AIM :- To Implement N-Queens problem using Backtracking
CODE :-
#include <iostream>
#include <vector>
using namespace std;
bool isSafe(const vector<vector<int>>& board, int row, int col, int N) {
for (int i = 0; i < col; i++)
if (board[row][i])
return false;
for (int i = row, j = col; i >= 0 && j >= 0; i--, j--)
if (board[i][j])
return false;
for (int i = row, j = col; i < N && j >= 0; i++, j--)
if (board[i][j])
return false;
return true;
}
void printSolution(const vector<vector<int>>& board, int N) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cout << (board[i][j] ? "Q " : ". ");
} cout << endl;
} cout << endl;
} void solveNQueensUtil(vector<vector<int>>& board, int col, int N) {
if (col >= N) {
printSolution(board, N);
return;
}
for (int i = 0; i < N; i++) {
if (isSafe(board, i, col, N)) {
board[i][col] = 1;
solveNQueensUtil(board, col + 1, N);
board[i][col] = 0;
}}}
int main() {
int N = 5; // You can change N to test with different sizes
vector<vector<int>> board(N, vector<int>(N, 0));
cout << "Finding solutions for " << N << " Queens:\n\n";
solveNQueensUtil(board, 0, N);
return 0;
}
OUTPUT :-
EXPERIMENT – 8
AIM :- To Implement Matrix Multiplication and analyse it’s time complexity
CODE :-
#include <iostream>
#include <vector>
using namespace std;
void multiplyMatrix(const vector<vector<int>>& A, const vector<vector<int>>& B,
int n) {
vector<vector<int>> result(n, vector<int>(n, 0));
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
for(int k = 0; k < n; k++) {
result[i][j] += A[i][k] * B[k][j];
}
}
}
cout << "---- Resultant Matrix ---- \n";
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
cout << "[" << result[i][j] << "]\t"; // Use brackets for each element
}
cout << endl;
}
}
int main() {
int n = 3;
vector<vector<int>> A = {
{12, 2, 3},
{43, 9, 21},
{7, 4, 12}
};
vector<vector<int>> B = {
{92, 8, 7},
{6, 15, 4},
{31, 26, 1}
};
cout << "---- Matrix A ---- \n";
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++)
cout << "[" << A[i][j] << "]\t"; // Use brackets for better visual distinction
cout << endl;
}
cout << "\n---- Matrix B ---- \n";
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++)
cout << "[" << B[i][j] << "]\t";
cout << endl;
}
cout << "\n";
multiplyMatrix(A, B, n);
return 0;
}
OUTPUT :-
-> STANDARD MATRIX MULTIPLICATION:
1.) Time Complexity: O(N³)
2.) Space Complexity: O(N²)
EXPERIMENT – 9
AIM :- To Implement Longest Common Subsequence problem and analyse it’s time
complexity
CODE :-
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void printLCS(const vector<vector<int>>& dp, const string& X, const string& Y, int
m, int n) {
string lcs = "";
int i = m, j = n;
while (i > 0 && j > 0) {
if (X[i-1] == Y[j-1]) {
lcs = X[i-1] + lcs; i--; j--;
} else if (dp[i-1][j] > dp[i][j-1]) {
i--;
} else {
j--;
}}
cout << "Longest Common Subsequence: \"" << lcs << "\"\n";
}
int LCS(const string& X, const string& Y) {
int m = X.length();
int n = Y.length();
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
for(int i = 1; i <= m; i++) {
for(int j = 1; j <= n; j++) {
if(X[i-1] == Y[j-1])
dp[i][j] = dp[i-1][j-1] + 1;
else
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
cout << "\nDynamic Programming Table:\n";
cout << " ";
for (char c : Y) cout << " " << c;
cout << endl;
for(int i = 0; i <= m; i++) {
if (i > 0) cout << X[i-1] << " ";
else cout << " ";
for(int j = 0; j <= n; j++) {
cout << dp[i][j] << " ";
}
cout << endl;
}
cout << "\n";
printLCS(dp, X, Y, m, n);
return dp[m][n];
}
int main() {
string X = "BAGGTABC";
string Y = "GXTXAYBC";
cout << "Input Strings:\n";
cout << "String 1: \"" << X << "\"\n";
cout << "String 2: \"" << Y << "\"\n";
int length = LCS(X, Y);
cout << "Length of Longest Common Subsequence: " << length << "\n";
return 0;
}
OUTPUT :-
Longest Common Subsequence ( Dynamic Programming):
1.) Time Complexity: O(N*m)
2.) Space Complexity: O(N*m)
EXPERIMENT – 10 (A)
AIM :- To Implement Naive String Searching algorithm and analyse time complexity
CODE :-
#include <iostream>
#include <string>
using namespace std;
void naiveStringSearch(const string& txt, const string& pat) {
int N = txt.length();
int M = pat.length();
bool found = false;
for (int i = 0; i <= N - M; i++) {
int j;
for (j = 0; j < M; j++) {
if (txt[i + j] != pat[j])
break;
}
if (j == M) {
cout << "✔ Pattern found at index: " << i << endl;
found = true;
}
}
if (!found) {
cout << "❌ Pattern not found in the text." << endl;
}
}
int main() {
string txt = "CDBABDABACDFABABCABAB";
string pat = "FABABCABAB";
cout << "Searching for pattern: \"" << pat << "\" in text: \"" << txt << "\"..." << endl;
naiveStringSearch(txt, pat);
return 0;
}
OUTPUT :-
-> Naive String Searching:
1.) Time Complexity: O(N*m)
2.) Space Complexity: O(1)
EXPERIMENT – 10 (B)
AIM :- To Implement Rabin Karp algorithm and analyse time complexity
CODE :-
#include <iostream>
#include <string>
using namespace std;
#define d 256
const int q = 101;
void rabinKarpSearch(string pat, string txt, int q) {
int M = pat.length();
int N = txt.length();
int i, j; int p = 0; int t = 0; int h = 1;
for (i = 0; i < M - 1; i++)
h = (h * d) % q;
for (i = 0; i < M; i++) {
p = (d * p + pat[i]) % q;
t = (d * t + txt[i]) % q;
cout << "Searching for pattern: \"" << pat << "\" in text: \"" << txt << "\"...\n";
bool found = false;
for (i = 0; i <= N - M; i++) {
if (p == t) {
for (j = 0; j < M; j++) {
if (txt[i + j] != pat[j])
break;
}
if (j == M) {
cout << "Pattern found at index: " << i << endl;
found = true;
} } if (i < N - M) {
t = (d * (t - txt[i] * h) + txt[i + M]) % q;
if (t < 0)
t = (t + q);
}}
if (!found) {
cout << "Pattern not found in the text." << endl;
}}
int main() {
string txt = "BOOKS FOR STUDENTS";
string pat = "STUDENT";
rabinKarpSearch(pat, txt, q);
return 0;
OUTPUT :-
-> Rabin Karp Algorithm:
1.) Time Complexity:
BEST :- O(N + m)
WORST:- O(N*m)
2.) Space Complexity: O(1)
EXPERIMENT – 10 (C)
AIM :- To Implement Knuth Morris Pratt algorithm and analyse time complexity
CODE :-
#include <iostream>
#include <string>
using namespace std;
void computeLPSArray(string pat, int M, int* lps) {
int len = 0;
lps[0] = 0;
int i = 1;
while (i < M) {
if (pat[i] == pat[len]) {
len++;
lps[i] = len;
i++;
} else {
if (len != 0) {
len = lps[len - 1];
} else {
lps[i] = 0;
i++;
}
}
void KMPSearch(string pat, string txt) {
int M = pat.length();
int N = txt.length();
int lps[M];
computeLPSArray(pat, M, lps);
int i = 0; // index for txt
int j = 0; // index for pat
bool found = false; // Flag to check if pattern is found
while (i < N) {
if (pat[j] == txt[i]) {
i++;
j++;
if (j == M) {
cout << "🎉 Pattern found at index " << i - j << " in the text!" << endl;
found = true;
j = lps[j - 1];
} else if (i < N && pat[j] != txt[i]) {
if (j != 0)
j = lps[j - 1];
else
i++;
}
if (!found) {
cout << "❌ No occurrences of the pattern found in the text." << endl;
int main() {
string txt = "SSDNBABDSDAABACDSAKABABCABAB";
string pat = "SAKABABCABAB";
cout << "Q Searching for the pattern: \"" << pat << "\" in the text: \"" << txt <<
"\"...\n";
KMPSearch(pat, txt);
return 0;
OUTPUT :-
-> Knuth Morris Pratt Algorithm:
1.) Time Complexity: O(N + m)
2.) Space Complexity: O(m)