0% found this document useful (0 votes)
20 views22 pages

Lab Assessment-3: Jayendra Jamadar

Uploaded by

Jayendra Jamadar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views22 pages

Lab Assessment-3: Jayendra Jamadar

Uploaded by

Jayendra Jamadar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

LAB ASSESSMENT-3

JAYENDRA JAMADAR

RegNo: 23BBS0078

Date
23/04/24

Data Structures and Algorithm
LAB ASSESSMENT-5
Q1. Consider the following list of names. Sort them in a nondecreasing order using Divide and
Conquer strategy that uses a pivot element as the last element of the array. Subhas, Akshit, Akshay,
Hamsa, Aravind, Anirudh, Bharat, Catharine, Pitts, Mecullay, Oscar Also determine the complexity
of the algorithm in the worst case.

ANS:
PSEUDOCODE:

quicksort(arr[], low, high):


if low < high: pivot_index = partition(arr,
low, high)

quicksort(arr, low, pivot_index - 1)


quicksort(arr, pivot_index + 1, high)

partition(arr[], low, high):


pivot = arr[high] i = low
- 1

for j from low to high - 1:


if arr[j] <= pivot: i = i
+ 1
swap(arr[i], arr[j]) swap(arr[i +

1], arr[high]) return i + 1

Code:
#include <stdio.h>
#include <string.h>

void swapStrings(char *str1, char *str2)


{
char temp[100];
strcpy(temp, str1);
strcpy(str1, str2);
strcpy(str2, temp);

LA-5 PAGE 2
}

int partitionStrings(char arr[][100], int


low, int high) {
char pivot[100];
strcpy(pivot, arr[high]);
int i = low - 1;

for (int j = low; j <= high - 1; j++)


{
if (strcmp(arr[j], pivot) < 0) {
i++;
swapStrings(arr[i], arr[j]);
}
}
swapStrings(arr[i + 1], arr[high]);
return (i + 1);
}

void quickSortStrings(char arr[][100],


int low, int high) {
if (low < high) {
int pi = partitionStrings(arr,
low, high);
quickSortStrings(arr, low, pi -
1);
quickSortStrings(arr, pi + 1,
high);
}
}

int main() {
char names[][100] = {"Subhas",
"Akshit", "Akshay", "Hamsa", "Aravind",
"Anirudh",
"Bharat", "Catharine", "Pitts",
"Mecullay", "Oscar"};
int n = sizeof(names) /
sizeof(names[0]);

quickSortStrings(names, 0, n - 1);
printf("Sorted names:\n");
for (int i = 0; i < n; i++) {
printf("%s\t", names[i]);
}
return 0;
}

LA-5 PAGE 3
OUTPUT:

Complexity Analysis:
● Time Complexity: In the worst case, the partition operation takes O(n) time, and since we do
this recursively for n elements, the worst-case time complexity is O(n^2 ). However, on
average, Quicksort runs in O(nlogn) time.
● Space Complexity: The space complexity of the algorithm is O(logn) due to the recursive calls
on the stack.

ITERATIONS:
1. Iteration 6:
● The pivot is "Oscar".
● All elements to the left of "Oscar" are less than it, and all elements to the right are greater.
2. Iteration 1:
● The pivot is "Aravind".
● All elements to the left of "Aravind" are less than it, and all elements to the right are greater.
3. Iteration 4:
● The pivot is "Catharine".
● All elements to the left of "Catharine" are less than it, and all elements to the right are greater.
4. Iteration 0:
● The pivot is "Akshit".
● All elements to the left of "Akshit" are less than it, and all elements to the right are greater.
5. Iteration 9:
● The pivot is "Pitts".
● All elements to the left of "Pitts" are less than it, and all elements to the right are greater.
6. Iteration 8:
● The pivot is "Mecullay".
● All elements to the left of "Mecullay" are less than it, and all elements to the right are greater.
7. Iteration 10:
● The pivot is "Subhas".
● All elements to the left of "Subhas" are less than it, and all elements to the right are greater.
8. Iteration 7:
● The pivot is "Oscar".
● All elements to the left of "Oscar" are less than it, and all elements to the right are greater.

LA-5 PAGE 4
Q2.Consider a set of positive distinct integers(A) and a value (m). Determine if there is a subset of A
whose sum is divisible by m. If there exists such subset then display “YES” otherwise display “NO”.
Also compute the complexity of your algorithm. Note: Size of set |A|<1000000 and m<=1000
Sample Input: A={3,1,7,5}, m=6; Sample Output: YES

ANS:
PSEUDOCODE:
1. Initialize a boolean array dp of size m where dp[i] represents whether there exists a subset
with sum divisible by m.
2. Iterate through each element set[i] in the set.
3. Create a temporary array temp and copy values of dp to it.
4. For each value j in dp, if dp[j] is true, update temp[(j + set[i]) % m] to true.
5. Copy values of temp back to dp.
6. Check if dp[0] is true, if yes, return true, else false.

CODE:
#include <stdio.h>
#include <stdbool.h>

bool isSubsetSumDivisible(int set[], int size, int divisor) {


bool dp[divisor];
for (int i = 0; i < divisor; i++)
dp[i] = false;
dp[0] = true;
for (int i = 0; i < size; i++) {
bool temp[divisor];
for (int j = 0; j < divisor; j++)
temp[j] = dp[j];

for (int j = 0; j < divisor; j++) {


if (dp[j])
temp[(j + set[i]) % divisor] = true;
}
for (int j = 0; j < divisor; j++)
dp[j] = temp[j];
}

LA-5 PAGE 5
return dp[0];
}

int main() {
int set[] = {3, 1, 7, 5};
int size = sizeof(set) / sizeof(set[0]);
int divisor = 6;
if (isSubsetSumDivisible(set, size, divisor))
printf("YES\n");
else
printf("NO\n");

return 0;
}

Complexity Analysis:
- Time Complexity: In the `isSubsetSumDivisible` function, there are two nested loops iterating
over `n` and `m`, where `n` is the number of elements in the set and `m` is the value of the divisor.
Inside the innermost loop, the operations take constant time. So, the overall time complexity is O(n *
m).

- Space Complexity: The space complexity is determined by the space used by the `dp` array,
which has a size of `m`. So, the space complexity is O(m).

OUTPUT:

LA-5 PAGE 6
Q3. Write a program to find the shortest path between source node to
destination node in the given graph using dijkstra’s algorithm

ANS:
Pseudocode:
function Dijkstra(Graph, source, destination):
distances = array of size Graph.num_nodes initialized with infinity distances[source]

= 0 visited = array of size Graph.num_nodes initialized with false parent = array of

size Graph.num_nodes initialized with -1

for count from 1 to Graph.num_nodes - 1:


minDist = infinity minVertex = -1 for each
vertex in Graph:
if distances[vertex] < minDist and not visited[vertex]:
minDist = distances[vertex] minVertex = vertex

visited[minVertex] = true

for each neighbor of minVertex:


if not visited[neighbor] and distances[minVertex] +
edge_weight(minVertex, neighbor) < distances[neighbor]:
distances[neighbor] = distances[minVertex] + edge_weight(minVertex,
neighbor) parent[neighbor] = minVertex

path = [] current = destination while


current != -1:
path.prepend(current) current =
parent[current] print("Shortest path from",
source, "to", destination, ":", path)

source = 0 destination = 5
Dijkstra(graph, source, destination)

CODE:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

LA-5 PAGE 7
#define MAX_NODES 100
#define INF INT_MAX

struct Edge {
int destination;
int weight;
struct Edge* next;
};

struct Vertex {
struct Edge* head;
};

struct Graph {
int num_nodes;
struct Vertex* vertices;
};

struct Edge* createEdge(int destination, int weight) {


struct Edge* newEdge = (struct Edge*)malloc(sizeof(struct Edge));
newEdge->destination = destination;
newEdge->weight = weight;
newEdge->next = NULL;
return newEdge;
}

struct Graph* createGraph(int num_nodes) {


struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph));
graph->num_nodes = num_nodes;
graph->vertices = (struct Vertex*)malloc(num_nodes * sizeof(struct
Vertex));
for (int i = 0; i < num_nodes; i++) {
graph->vertices[i].head = NULL;
}
return graph;
}

void addEdge(struct Graph* graph, int src, int dest, int weight) {
struct Edge* newEdge = createEdge(dest, weight);
newEdge->next = graph->vertices[src].head;
graph->vertices[src].head = newEdge;
}

void dijkstra(struct Graph* graph, int src, int dest) {

LA-5 PAGE 8
int* distances = (int*)malloc(graph->num_nodes * sizeof(int));
int* visited = (int*)malloc(graph->num_nodes * sizeof(int));
int* parent = (int*)malloc(graph->num_nodes * sizeof(int));

for (int i = 0; i < graph->num_nodes; i++) {


distances[i] = INF;
visited[i] = 0;
parent[i] = -1;
}

distances[src] = 0;
for (int count = 0; count < graph->num_nodes - 1; count++) {
int min_dist = INF;
int u;
for (int v = 0; v < graph->num_nodes; v++) {
if (visited[v] == 0 && distances[v] <= min_dist) {
min_dist = distances[v];
u = v;
}
}
visited[u] = 1;
struct Edge* edge = graph->vertices[u].head;
while (edge != NULL) {
int v = edge->destination;
if (!visited[v] && distances[u] != INF && distances[u] + edge-
>weight < distances[v]) {
distances[v] = distances[u] + edge->weight;
parent[v] = u;
}
edge = edge->next;
}
}

printf("Shortest path from %d to %d: ", src, dest);


int current = dest;
while (current != -1) {
printf("%d ", current);
current = parent[current];
}
printf("\n");

free(distances);
free(visited);
free(parent);
}

LA-5 PAGE 9
int main() {
int num_nodes = 6;
struct Graph* graph = createGraph(num_nodes);
addEdge(graph, 0, 1, 5);
addEdge(graph, 0, 2, 10);
addEdge(graph, 1, 2, 3);
addEdge(graph, 1, 3, 8);
addEdge(graph, 2, 3, 1);
addEdge(graph, 2, 4, 2);
addEdge(graph, 3, 4, 6);
addEdge(graph, 3, 5, 9);
addEdge(graph, 4, 5, 4);
int src = 0, dest = 5;
dijkstra(graph, src, dest);
return 0;
}

OUTPUT:

Q4. Write a program to perform BFS and DFS on a given undirected graph.

ANS:
Pseudocode:
BFS(graph, start):
Initialize an empty queue
Mark all nodes as not visited
Mark start node as visited Enqueue start node into
the queue while queue is not empty:
Dequeue a node from the queue and print it For each neighbor of
the dequeued node:
If the neighbor is not visited:
Mark it as visited

LA-5 PAGE 10
Enqueue it into the queue

DFS(graph, start):
Mark all nodes as not visited
Call DFS_recursive(graph, start)

DFS_recursive(graph, current):
Mark current node as visited
Print current node
For each neighbor of current node:
If neighbor is not visited:
Call DFS_recursive(graph, neighbor)

Code:
#include <stdio.h>
#include <stdlib.h>

#define MAX_NODES 100

struct Vertex {
int value;
struct Vertex* next;
};

struct Network {
int node_count;
struct Vertex* connections[MAX_NODES];
int checked[MAX_NODES];
};

struct Vertex* createVertex(int value) {


struct Vertex* newVertex = (struct Vertex*)malloc(sizeof(struct
Vertex));
newVertex->value = value;
newVertex->next = NULL;
return newVertex;
}

void addConnection(struct Network* network, int from, int to) {

LA-5 PAGE 11
struct Vertex* newVertex = createVertex(to);
newVertex->next = network->connections[from];
network->connections[from] = newVertex;

newVertex = createVertex(from);
newVertex->next = network->connections[to];
network->connections[to] = newVertex;
}

void breadthFirstSearch(struct Network* network, int start) {


int queue[MAX_NODES];
int front = -1, rear = -1;
network->checked[start] = 1;
queue[++rear] = start;
while (front != rear) {
int current = queue[++front];
printf("%d ", current);
struct Vertex* temp = network->connections[current];
while (temp != NULL) {
int neighbor = temp->value;
if (!network->checked[neighbor]) {
network->checked[neighbor] = 1;
queue[++rear] = neighbor;
}
temp = temp->next;
}
}
}

void depthFirstSearchRecursive(struct Network* network, int current) {


printf("%d ", current);
network->checked[current] = 1;
struct Vertex* temp = network->connections[current];
while (temp != NULL) {
int neighbor = temp->value;
if (!network->checked[neighbor]) {
depthFirstSearchRecursive(network, neighbor);
}

LA-5 PAGE 12
temp = temp->next;
}
}

void depthFirstSearch(struct Network* network, int start) {


for (int i = 0; i < network->node_count; i++) {
network->checked[i] = 0;
}
depthFirstSearchRecursive(network, start);
}

int main() {
struct Network* network = (struct Network*)malloc(sizeof(struct
Network));
network->node_count = 6;
for (int i = 0; i < network->node_count; i++) {
network->connections[i] = NULL;
network->checked[i] = 0;
}

addConnection(network, 0, 1);
addConnection(network, 0, 2);
addConnection(network, 1, 3);
addConnection(network, 1, 4);
addConnection(network, 2, 4);
addConnection(network, 3, 4);
addConnection(network, 3, 5);
addConnection(network, 4, 5);

printf("Breadth-First Search Traversal: ");


breadthFirstSearch(network, 0);
printf("\n");

printf("Depth-First Search Traversal: ");


depthFirstSearch(network, 0);
printf("\n");

return 0;
}

LA-5 PAGE 13
OUTPUT:

Q5. Write a program to find the minimum spanning tree on a given undirected graph using prims’s
algorithm.

ANS:
Pseudocode:
PrimMST(graph): parent[MAX_NODES] // Array to store constructed MST key[MAX_NODES] //
Key values used to pick minimum weight edge in cut mstSet[MAX_NODES] // To represent set of
vertices included in MST

for each vertex in graph: key[vertex] = INFINITY


mstSet[vertex] = false

key[0] = 0 // Make key 0 so that this vertex is picked as first vertex parent[0] = -1 // First node is
always root of MST

for count from 1 to graph.num_nodes - 1: u = minKey(key,

mstSet, graph.num_nodes) mstSet[u] = true

for each neighbor of u:


if neighbor is not in MST set and weight of edge (u, neighbor) is less
than key[neighbor]:
parent[neighbor] = u key[neighbor] = weight of edge (u,

neighbor) printMST(parent, graph.num_nodes, graph)

LA-5 PAGE 14
Code:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define MAX_NODES 100

struct Edge {
int destination;
int weight;
struct Edge* next;
};

struct AdjacencyList {
struct Edge* head;
};

struct Graph {
int num_nodes;
struct AdjacencyList*
adjacency_lists;
};

struct Edge* createEdge(int destination,


int weight) {
struct Edge* newEdge = (struct
Edge*)malloc(sizeof(struct Edge));
newEdge->destination = destination;
newEdge->weight = weight;
newEdge->next = NULL;
return newEdge;
}

struct Graph* createGraph(int num_nodes)


{
struct Graph* graph = (struct
Graph*)malloc(sizeof(struct Graph));
graph->num_nodes = num_nodes;
graph->adjacency_lists = (struct
AdjacencyList*)malloc(num_nodes *
sizeof(struct AdjacencyList));
for (int i = 0; i < num_nodes; i++) {
graph->adjacency_lists[i].head =
NULL;
}
return graph;

LA-5 PAGE 15
}

void addEdge(struct Graph* graph, int


src, int dest, int weight) {
struct Edge* newEdge =
createEdge(dest, weight);
newEdge->next = graph-
>adjacency_lists[src].head;
graph->adjacency_lists[src].head =
newEdge;

newEdge = createEdge(src, weight);


newEdge->next = graph-
>adjacency_lists[dest].head;
graph->adjacency_lists[dest].head =
newEdge;
}

int minKey(int key[], int mstSet[], int


num_nodes) {
int min = INT_MAX, min_index;
for (int v = 0; v < num_nodes; v++) {
if (mstSet[v] == 0 && key[v] <
min) {
min = key[v];
min_index = v;
}
}
return min_index;
}

void printMST(int parent[], int


num_nodes, int
graph[MAX_NODES][MAX_NODES]) {
printf("Edge\tWeight\n");
for (int i = 1; i < num_nodes; i++) {
printf("%d - %d\t%d\n",
parent[i], i, graph[i][parent[i]]);
}
}

void primMST(struct Graph* graph) {


int parent[MAX_NODES];
int key[MAX_NODES];
int mstSet[MAX_NODES];

for (int i = 0; i < graph->num_nodes;


i++) {

LA-5 PAGE 16
key[i] = INT_MAX;
mstSet[i] = 0;
}

key[0] = 0;
parent[0] = -1;

for (int count = 0; count < graph-


>num_nodes - 1; count++) {
int u = minKey(key, mstSet,
graph->num_nodes);
mstSet[u] = 1;

struct Edge* temp = graph-


>adjacency_lists[u].head;
while (temp != NULL) {
int v = temp->destination;
int weight = temp->weight;
if (mstSet[v] == 0 && weight
< key[v]) {
parent[v] = u;
key[v] = weight;
}
temp = temp->next;
}
}

printMST(parent, graph->num_nodes,
adjacency_matrix);
}

int main() {
int num_nodes = 5;
struct Graph* graph =
createGraph(num_nodes);
int
adjacency_matrix[MAX_NODES][MAX_NODES] =
{
{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}
};

for (int i = 0; i < num_nodes; i++) {


for (int j = 0; j < num_nodes;
j++) {

LA-5 PAGE 17
if (adjacency_matrix[i][j] !=
0) {
addEdge(graph, i, j,
adjacency_matrix[i][j]);
}
}
}

printf("Minimum Spanning Tree (MST)


using Prim's Algorithm:\n");
primMST(graph);

return 0;
}

OUTPUT:

Q6. Write a program to find the minimum spanning tree on a given undirected graph using Kruskal’s
algorithm

ANS:
Pseudocode:
Kruskal(Graph G):
Initialize an empty priority queue PQ
Initialize an empty set S to store the spanning tree edges
Initialize an array parent[] to keep track of the parent of each vertex

for each vertex v in G: MakeSet(v)

Sort the edges of G by their weights in non-decreasing order and add them to
PQ

while PQ is not empty:

LA-5 PAGE 18
Get the edge (u, v) with the minimum weight from PQ Remove (u, v) from PQ

if Find(u) ≠ Find(v): // Check if adding (u, v) creates a cycle


Add (u, v) to S
Union(u, v) // Merge the sets containing u and v return S

CODE:
#include <stdio.h>
#include <stdlib.h>

struct Edge {
int source, destination, weight;
};

struct Graph {
int vertices, edges;
struct Edge* edges_list;
};

struct Graph* createGraph(int vertices,


int edges) {
struct Graph* graph = (struct
Graph*)malloc(sizeof(struct Graph));
graph->vertices = vertices;
graph->edges = edges;
graph->edges_list = (struct
Edge*)malloc(edges * sizeof(struct
Edge));
return graph;
}

struct Subset {
int parent;
int rank;
};

int find(struct Subset subsets[], int i)


{
if (subsets[i].parent != i)
subsets[i].parent = find(subsets,
subsets[i].parent);
return subsets[i].parent;
}

LA-5 PAGE 19
void unionSets(struct Subset subsets[],
int x, int y) {
int xroot = find(subsets, x);
int yroot = find(subsets, y);

if (subsets[xroot].rank <
subsets[yroot].rank)
subsets[xroot].parent = yroot;
else if (subsets[xroot].rank >
subsets[yroot].rank)
subsets[yroot].parent = xroot;
else {
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
}
}

int compareEdges(const void* a, const


void* b) {
struct Edge* edge1 = (struct Edge*)a;
struct Edge* edge2 = (struct Edge*)b;
return edge1->weight - edge2->weight;
}

void KruskalMST(struct Graph* graph) {


int vertices = graph->vertices;
struct Edge result[vertices];
int edge_count = 0;
int i = 0;

qsort(graph->edges_list, graph-
>edges, sizeof(struct Edge),
compareEdges);

struct Subset* subsets = (struct


Subset*)malloc(vertices * sizeof(struct
Subset));
for (int v = 0; v < vertices; ++v) {
subsets[v].parent = v;
subsets[v].rank = 0;
}

while (edge_count < vertices - 1 && i


< graph->edges) {
struct Edge next_edge = graph-
>edges_list[i++];

LA-5 PAGE 20
int x = find(subsets,
next_edge.source);
int y = find(subsets,
next_edge.destination);

if (x != y) {
result[edge_count++] =
next_edge;
unionSets(subsets, x, y);
}
}

printf("Edges in the Minimum Spanning


Tree:\n");
for (i = 0; i < edge_count; ++i)
printf("%d -- %d == %d\n",
result[i].source, result[i].destination,
result[i].weight);

free(subsets);
}

int main() {
int vertices = 4;
int edges = 5;
struct Graph* graph =
createGraph(vertices, edges);

graph->edges_list[0].source = 0;
graph->edges_list[0].destination = 1;
graph->edges_list[0].weight = 10;

graph->edges_list[1].source = 0;
graph->edges_list[1].destination = 2;
graph->edges_list[1].weight = 6;

graph->edges_list[2].source = 0;
graph->edges_list[2].destination = 3;
graph->edges_list[2].weight = 5;

graph->edges_list[3].source = 1;
graph->edges_list[3].destination = 3;
graph->edges_list[3].weight = 15;

graph->edges_list[4].source = 2;
graph->edges_list[4].destination = 3;
graph->edges_list[4].weight = 4;

LA-5 PAGE 21
KruskalMST(graph);

free(graph->edges_list);
free(graph);

return 0;
}

OUTPUT:

LA-5 PAGE 22

You might also like