AoA Lab Manual (1)
AoA Lab Manual (1)
S No. CONTENT
RTU Syllabus
1.
Do’s & Don’ts
2.
4. PEO/ PO/PSO/CO
5. Lab Plan
DO’s
1. Please switch off the Mobile/Cell phone before entering Lab.
2. Enter the Lab with complete source code and data.
3. Check whether all peripheral are available at your desktop before proceeding for program.
4. Intimate the lab In-charge whenever you are incompatible in using the system or in case
software get corrupted/ infected by virus.
5. Arrange all the peripheral and seats before leaving the lab.
6. Properly shut down the system before leaving lab.
7. Keep the bag outside in the racks.
8. Enter the lab on time and leave at proper time.
9. Maintain the decorum of the lab.
10. Utilize lab hours in the corresponding experiment.
11. Get your CD/Pen drive checked by lab in charge before using it in the lab.
DONT’S
1. No one is allowed to bring storage devices like Pan Drive /Floppy etc. in the lab.
2. Don’t mishandle the system.
3. Don’t leave the system on standing for long
4. Don’t bring any external material in the lab.
5. Don’t make noise in the lab.
6. Don’t bring the mobile in the lab. If extremely necessary then keep ringers off.
7. Don’t enter in the lab without permission of lab In-charge.
8. Don’t litter in the lab.
9. Don’t delete or make any modification in system files. Don’t carry any lab equipments
outside the lab.
General Instructions
Maintain separate observation copy for each laboratory.
Observations or readings should be taken only in the observation copy.
Get the readings counter signed by the faculty after the completion of the experiment.
Maintain Index column in the observation copy and get the signature of the faculty before
leaving the lab.
Life Long Learning: The Graduate of Computer Science & Engineering shall be
able to learn, innovate, and evolve new technology lifelong.
PEO-2
COURSE OUTCOMES:
The study of subject Data Structures and algorithms 3CS4-21 in undergraduate program in
Computer Science Engineering Branch will achieve the following major objectives-
1. This Lab helps the student to understand the need of data structures and how different data
structures are to be implemented.
2. This lab provide ability to apply algorithms to different problems and identify the best
algorithm in terms of space and time.
3. This lab helps the student to choose appropriate algorithms, optimize their implementations,
and evaluate trade-offs between different approaches. This objective encourages critical
thinking and creativity in algorithm design.
4. This lab helps the students to implement various sorting algorithms, search algorithms, data
structures (linked lists, trees, graphs, etc.), and analyze their performance in terms of time and
space complexity.
1 13 23 33 42 -5
2 -6
- -7
- -8
- -9
- 10
- O
- O
2 -1
3 23
- -
2 3 3 3 2 2 - - - - - - 2 3 3
1 1
3 3 3 3 2 2 - - - - - - 2 3 3
1 2
4 3 3 3 1 2 - - - - - - 2 2 2
Aim: Sort a given set of elements using the Quicksort method and determine the
time required to sort the elements. Repeat the experiment for different values
of n, the number of elements in the list to be sorted and plot a graph of the
time taken versus n. The details can be read from a file or can be generated
using the random number generator.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main() {
int n, a[1000], k, limit; // Added 'limit' variable
clock_t st, et;
double ts;
clrscr();
printf("\nEnter How many Numbers: ");
scanf("%d", &n);
printf("Enter the upper limit for random numbers: "); // Prompt for limit
scanf("%d", &limit);
st = clock();
QuickSort(a, 1, n);
et = clock();
ts = (double)(et - st) / CLOCKS_PER_SEC;
printf("\nSorted Numbers are: \n ");
for (k = 1; k <= n; k++)
printf("%d\t", a[k]);
printf("\nThe time taken is %e", ts);
getch();
return 0;
}
Output:
Q4: What are some advantages of using Quicksort over other sorting algorithms?
Ans: Quicksort is known for its efficient average-case performance, making it one of the fastest
sorting algorithms for larger datasets. It's also an in-place sorting algorithm, meaning it doesn't require
additional memory for sorting. With proper pivot selection, it can perform better than other O(n log n)
algorithms in practice.
Q5: How can you generate different values of 'n' for the experiment?
Ans: You can manually input different sizes of arrays, read 'n' values from a file containing element
details, or use a random number generator to generate arrays of varying lengths.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int n, k, lim;
clock_t st, et;
double ts;
printf("Enter the number of elements: ");
scanf("%d", &n);
st = clock();
MergeSort(a, 0, n - 1); // Passing array with indices 0 to n-1
et = clock();
ts = (double)(et - st) / CLOCKS_PER_SEC;
printf("\nSorted Numbers are:\n");
for (k = 0; k < n; k++)
printf("%d\t", a[k]);
printf("\nThe time taken is %e\n", ts);
return 0;
}
Output:
#include <stdio.h>
#include <stdlib.h>
struct Graph {
int V;
int** adjacency_matrix;
};
return graph;
}
void DFS(struct Graph* graph, int v, int* visited, int* topological_order, int* index) {
visited[v] = 1;
topological_order[(*index)--] = v;
}
free(visited);
free(topological_order);
}
int main() {
int V, E;
printf("Enter the number of vertices: ");
scanf("%d", &V);
return 0;
}
Output:
Q1: What is a digraph? And what is the concept of topological ordering of vertices in a
digraph?
Ans: A digraph, or directed graph, is a graph in which edges have a specific direction,
indicating a one-way relationship between vertices.
A topological ordering is a linear ordering of the vertices in a digraph such that for every
directed edge (u, v), vertex u comes before vertex v in the ordering.
Q4: What is the key property that a digraph must satisfy for a topological ordering to
exist?
Ans: A digraph must be a Directed Acyclic Graph (DAG) for a valid topological ordering to
exist. Cycles in the graph would create contradictions in the ordering.
Q5: What is the time complexity of obtaining a topological ordering using depth-first
search?
Ans: The time complexity is O(V + E), where V is the number of vertices and E is the
number of edges in the graph.
#include <stdio.h>
#include <stdlib.h>
int main() {
int V;
printf("Enter the number of vertices: ");
scanf("%d", &V);
int graph[MAX_VERTICES][MAX_VERTICES];
transitiveClosure(V, graph);
return 0;
}
Output:
Q3: How does Warshall's algorithm represent the graph and its transitive closure?
Ans: Warshall's algorithm uses an adjacency matrix to represent the graph and updates a
separate matrix to represent the transitive closure.
#include <stdio.h>
return dp[n][capacity];
}
int main() {
int n, capacity;
return 0;
}
Output:
Q3: How does Dynamic Programming solve the 0/1 Knapsack problem efficiently?
Ans: Dynamic Programming solves the problem by building a table where each cell
represents the maximum value that can be obtained with a certain weight capacity and a
subset of items. The values are computed iteratively based on previously calculated
subproblems.
Q5: What is the advantage of using Dynamic Programming for the 0/1 Knapsack
problem?
Ans: Dynamic Programming avoids redundant calculations by storing intermediate results,
leading to significant efficiency improvements compared to naive recursive approaches.
#include <stdio.h>
#include <stdbool.h>
#include <limits.h>
return min_index;
}
int main() {
// Example graph represented as an adjacency matrix
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, source);
return 0;
}
Output:
Q5: How does Dijkstra's algorithm guarantee finding the shortest paths?
Ans: Dijkstra's algorithm iteratively selects vertices with the smallest tentative distance,
ensuring that all paths are explored and shortest distances are determined.
#include <stdio.h>
#include <stdlib.h>
if (xroot != yroot) {
// Function to find the Minimum Cost Spanning Tree using Kruskal's algorithm
void kruskalMST(struct Graph* graph) {
int V = graph->V;
struct Edge resultMST[V - 1]; // Stores the edges of the MST
int e = 0; // Index variable for resultMST
int i = 0; // Index variable for sorted edges array
// Keep adding edges to the MST until V-1 edges are added
while (e < V - 1 && i < graph->E) {
struct Edge nextEdge = graph->edges[i++];
int main() {
int V = 4; // Number of vertices
int E = 5; // Number of edges
struct Graph* graph = createGraph(V, E);
graph->edges[2].src = 0;
graph->edges[2].dest = 3;
graph->edges[2].weight = 5;
graph->edges[3].src = 1;
graph->edges[3].dest = 3;
graph->edges[3].weight = 15;
graph->edges[4].src = 2;
graph->edges[4].dest = 3;
graph->edges[4].weight = 4;
kruskalMST(graph);
return 0;
}
Output:
Viva Questions
Q1: What is a Minimum Cost Spanning Tree (MCST) in a graph?
Ans: A Minimum Cost Spanning Tree is a subset of the edges of an undirected graph that
connects all vertices with the minimum possible total edge weight and forms a tree without
any cycles.
Q3: How are edges sorted in Kruskal's algorithm and What is the time complexity of
Kruskal's algorithm?
Ans: Edges are typically sorted in ascending order of their weights to ensure that the smallest
weight edges are considered first.
The time complexity of Kruskal's algorithm is typically O(E log E), where E is the number of
edges in the graph
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
return graph;
}
printf("\n");
}
int main() {
struct Graph* graph = createGraph(6);
addEdge(graph, 0, 1);
addEdge(graph, 0, 2);
addEdge(graph, 1, 3);
addEdge(graph, 1, 4);
addEdge(graph, 2, 4);
addEdge(graph, 3, 5);
addEdge(graph, 4, 5);
BFS(graph, startVertex);
Output:
Q2: What is BFS in the context of graph traversal and what is the time complexity of
BFS traversal in a graph?
Ans: BFS stands for Breadth-First Search. It is a graph traversal algorithm that explores all
the vertices of a graph in breadthward motion, visiting all the neighbors of a node before
moving to their children.
The time complexity of BFS in a graph is O(V + E), where V is the number of vertices and E
is the number of edges.
#include <stdio.h>
#include <stdlib.h>
struct Graph {
int V;
int** adjacency_matrix;
};
return graph;
}
void DFS(struct Graph* graph, int v, int* visited, int* topological_order, int* index) {
visited[v] = 1;
topological_order[(*index)--] = v;
}
free(visited);
free(topological_order);
}
int main() {
int V, E;
printf("Enter the number of vertices: ");
scanf("%d", &V);
return 0;
}
Output:
Q2: What is the time complexity of the DFS-based graph connectivity check?
Ans: The time complexity is O(V + E), where V is the number of vertices, and E is the
number of edges in the graph.
#include <stdio.h>
#define MAX_VERTICES 10
int a, b, u, v, i, j, n, noe;
int vi[MAX_VERTICES], min, mc, c[MAX_VERTICES][MAX_VERTICES];
int main() {
printf("\nPrim's algorithm\n");
printf("\nEnter the number of vertices: ");
scanf("%d", &n);
printf("\nEnter the adjacency matrix:\n");
prims(c, n);
return 0;
}
if (vi[u] == 0 || vi[v] == 0) {
noe++;
printf("Edge(%d --> %d): %d\n", a, b, min);
mc += min;
vi[b] = 1;
}
Output:
Prim's algorithm
Viva Questions
Q3: Can Prim's algorithm handle graphs with negative edge weights?
Ans: Prim's algorithm, as traditionally implemented, does not handle negative edge weights.
It assumes that all edge weights are non-negative.
Q5: What is the difference between Prim's algorithm and Kruskal's algorithm for
finding MCSTs?
Ans: Prim's algorithm starts with a single vertex and grows the tree, while Kruskal's
algorithm starts with all vertices as individual trees and merges them.
#include <stdio.h>
int main() {
int V;
printf("Enter the number of vertices: ");
scanf("%d", &V);
int graph[MAX_VERTICES][MAX_VERTICES];
floydWarshall(graph, V);
return 0;
}
Output:
Q1: What is the All-Pairs Shortest Paths Problem, and what is Floyd's algorithm used
for?
Ans: The All-Pairs Shortest Paths Problem involves finding the shortest path between all
pairs of vertices in a weighted graph. Floyd's algorithm is specifically used to solve this
problem.
Q2: How does Floyd's algorithm work, and what is its time complexity?
Ans: Floyd's algorithm works by iteratively updating the shortest path matrix by considering
all possible intermediate vertices between any pair of vertices. It achieves this while having a
time complexity of O(V^3), where V represents the number of vertices in the graph.
Q3: What are the applications of the All-Pairs Shortest Paths Problem in real life, and
what data structures are commonly used to implement Floyd's algorithm?
Ans: The applications of the All-Pairs Shortest Paths Problem in real life include network
routing, navigation systems, social network analysis, and traffic flow optimization. To
implement Floyd's algorithm, a 2D matrix is commonly used to represent the graph and store
the shortest distances between vertices.
Q4: What is the main advantage of Floyd's algorithm over other algorithms for the All-
Pairs Shortest Paths Problem?
Ans: Floyd's algorithm is advantageous because it computes the shortest paths between all
pairs of vertices in a single pass, while other algorithms like Dijkstra's require multiple
passes.
Q5: What is the difference between Floyd's algorithm and Dijkstra's algorithm?
Ans: Floyd's algorithm finds the shortest paths between all pairs of vertices in a single pass,
while Dijkstra's algorithm finds the shortest path from a single source vertex to all other
vertices.
#define N 8 // Define the board size (change this value to solve for different N)
return true;
}
int main() {
int board[N][N];
if (solveNQueens(board, 0)) {
printf("Solution found:\n");
printBoard(board);
} else {
printf("No solution exists.\n");
}
return 0;
}
Output:
Solution found:
Q.......
......Q.
....Q...
.......Q
.Q......
...Q....
.....Q..
..Q.....
Viva Questions
Q5: How do you represent the chessboard in code for the N-Queens problem?
Ans: The chessboard can be represented using a 2D array where each cell represents a
square on the board, and the presence of a queen is indicated by a specific value.