Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
Course Code : MCSL-209
Course Title : Data Structures and Algorithms Lab
Assignment Number : BCA_NEW(III)L-209/Assignment/2025-26
1. Write an algorithm and program in ‘C’ language to merge two sorted linked lists. The
resultant linked list should be sorted. Use illustrations and diagrams to enhance the
explanations.
2. Write an algorithm and a program in ‘C’ language to insert and delete edges in an
adjacency list representation of an undirected graph. Make assumptions, if necessary.
Use illustrations and diagrams to enhance the explanations.
Question 1. : Write an algorithm and program in ‘C’ language to merge two sorted linked
lists. The resultant linked list should be sorted. Use illustrations and diagrams to enhance the
explanations.
Solution :
Algorithm to Merge Two Sorted Linked Lists
Handle Edge Cases:
o If list1 is empty, return list2.
o If list2 is empty, return list1.
Initialize Result List:
o Create a dummy node, dummyHead, to simplify the merging process. This node will not
be part of the final merged list but will serve as a starting point.
o Initialize a pointer, current, to dummyHead. This pointer will be used to build the
merged list.
Iterate and Merge:
o While both list1 and list2 are not empty:
Compare the data of the current nodes in list1 and list2.
If list1->data is less than or equal to list2->data:
Append list1's current node to current->next.
Move list1 to its next node.
Else (list2->data is smaller):
1
Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
Append list2's current node to current->next.
Move list2 to its next node.
Advance current to its newly appended node (current = current->next).
Append Remaining Nodes:
o After the loop, one of the lists might still have remaining nodes (since the other
became empty).
o If list1 is not empty, append the rest of list1 to current->next.
o If list2 is not empty, append the rest of list2 to current->next.
Return Result:
o The head of the merged sorted list is dummyHead->next. Return this.
C Program to Merge Two Sorted Linked Lists
#include <stdio.h>
#include <stdlib.h>
// Definition for a singly-linked list node.
struct ListNode {
int val;
struct ListNode *next;
};
// Function to create a new node
struct ListNode* createNode(int val) {
struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct
ListNode));
if (newNode == NULL) {
perror("Memory allocation failed");
exit(EXIT_FAILURE);
}
newNode->val = val;
newNode->next = NULL;
return newNode;
}
// Function to print a linked list
void printList(struct ListNode* head) {
struct ListNode* current = head;
while (current != NULL) {
printf("%d -> ", current->val);
current = current->next;
}
printf("NULL\n");
}
2
Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
// Function to merge two sorted linked lists
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode*
list2) {
// Handle edge cases
if (list1 == NULL) {
return list2;
}
if (list2 == NULL) {
return list1;
}
// Create a dummy head for the merged list
struct ListNode* dummyHead = createNode(0); // Dummy value, will be
discarded
struct ListNode* current = dummyHead;
// Merge the lists
while (list1 != NULL && list2 != NULL) {
if (list1->val <= list2->val) {
current->next = list1;
list1 = list1->next;
} else {
current->next = list2;
list2 = list2->next;
}
current = current->next;
}
// Append remaining nodes
if (list1 != NULL) {
current->next = list1;
} else if (list2 != NULL) {
current->next = list2;
}
// The actual head of the merged list is dummyHead->next
struct ListNode* mergedHead = dummyHead->next;
free(dummyHead); // Free the dummy node
return mergedHead;
}
int main() {
// Create first sorted linked list: 1 -> 3 -> 5
struct ListNode* list1 = createNode(1);
list1->next = createNode(3);
list1->next->next = createNode(5);
// Create second sorted linked list: 2 -> 4 -> 6
struct ListNode* list2 = createNode(2);
list2->next = createNode(4);
list2->next->next = createNode(6);
printf("List 1: ");
3
Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
printList(list1);
printf("List 2: ");
printList(list2);
// Merge the two lists
struct ListNode* mergedList = mergeTwoLists(list1, list2);
printf("Merged List: ");
printList(mergedList);
// Free allocated memory (important to prevent memory leaks)
struct ListNode* temp;
while (mergedList != NULL) {
temp = mergedList;
mergedList = mergedList->next;
free(temp);
}
return 0;
}
Merging Two Sorted Linked Lists with Illustrations
The process of merging two sorted linked lists can be visualized step-by-step to better
understand how the pointers are manipulated. The core idea is to traverse both input lists,
compare their current nodes, and link the smaller node to a new merged list.
Initial state
We start with two sorted linked lists, list1 and list2 .
A special dummy node is created. This node does not store data but serves as a fixed entry
point to simplify the logic for the merged list.
A tail pointer is created and initialized to the dummy node. This pointer will always point
to the last node of the new, merged list.
Diagram: Initial Setup
list1 (head1) -> [1] -> [3] -> [5] -> NULL
list2 (head2) -> [2] -> [4] -> [6] -> NULL
dummy -> [0] -> NULL
tail -> [0]
4
Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
Step 1: Compare heads of list1 and list2
Compare head1->data (1) and head2->data (2).
Since 1 <= 2, we append the node from list1 to the merged list.
tail->next now points to the node [1] .
tail is moved to the new last node ( [1] ).
head1 is advanced to the next node in list1 ( [3] ).
Diagram: After Step 1
list1 (head1) -> [3] -> [5] -> NULL
list2 (head2) -> [2] -> [4] -> [6] -> NULL
dummy -> [0] -> [1] -> NULL
tail -> [1]
Step 2: Compare new heads
The new heads are head1 ( [3] ) and head2 ( [2] ).
Compare head1->data (3) and head2->data (2).
Since 2 <= 3, we append the node from list2 to the merged list.
tail->next now points to the node [2] .
tail is moved to the new last node ( [2] ).
head2 is advanced to the next node in list2 ( [4] ).
Diagram: After Step 2
list1 (head1) -> [3] -> [5] -> NULL
list2 (head2) -> [4] -> [6] -> NULL
dummy -> [0] -> [1] -> [2] -> NULL
tail -> [2]
5
Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
Step 3: Continue the loop
The process repeats, comparing head1->data (3) and head2->data (4).
[3] is appended.
Then, head1 advances to [5] .
The new comparison is [5] vs [4] .
[4] is appended.
And so on, until one of the lists becomes NULL .
Diagram: After several steps
list1 (head1) -> [5] -> NULL
list2 (head2) -> [6] -> NULL
dummy -> [0] -> [1] -> [2] -> [3] -> [4] -> NULL
tail -> [4]
Step 4: Append remaining nodes
The loop terminates when head1 is at [5] and head2 is at [6] .
We compare head1->data (5) and head2->data (6).
[5] is appended, and head1 becomes NULL .
The loop condition ( head1 != NULL && head2 != NULL ) is now false.
Since list2 still has remaining nodes (the node [6] ), we simply append the rest
of list2 to the tail of the merged list.
Diagram: Final State
list1 (head1) -> NULL
list2 (head2) -> NULL
dummy -> [0] -> [1] -> [2] -> [3] -> [4] -> [5] -> [6] -> NULL
6
Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
tail -> [6]
Final result
The function returns the head of the merged list, which is dummy->next .
The dummy node is then freed.
The resulting linked list is 1 -> 2 -> 3 -> 4 -> 5 -> 6 .
Question 2. Write an algorithm and a program in ‘C’ language to insert and delete edges in
an adjacency list representation of an undirected graph. Make assumptions, if necessary. Use
illustrations and diagrams to enhance the explanations.
Algorithm for Edge Insertion and Deletion in an Adjacency List
1. Data Structure:
Represent the adjacency list using an array of linked lists. Each element of the
array adjLists[i] points to the head of a linked list containing all vertices adjacent
to vertex i.
Each node in the linked list will store the destination vertex.
2. Edge Insertion (addEdge(graph, src, dest))
Create a new node: Allocate memory for a new AdjListNode and set its dest field
to dest.
Insert into src's list: Set the next pointer of the new node to graph-
>adjLists[src] (making it the new head). Update graph->adjLists[src] to point to
the new node.
Insert into dest's list (for undirected graph): Create another
new AdjListNode with dest set to src. Insert this node into graph->adjLists[dest] in
the same manner.
3. Edge Deletion (deleteEdge(graph, src, dest))
Delete from src's list:
7
Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
Initialize current and prev pointers to traverse graph->adjLists[src].
Iterate through the list until current->dest == dest.
If current is the head, update graph->adjLists[src] to current->next.
Otherwise, set prev->next = current->next.
Free the memory of current.
Delete from dest's list (for undirected graph):
Repeat the same process for graph->adjLists[dest], searching for src and deleting
the corresponding node.
C Program
C
#include <stdio.h>
#include <stdlib.h>
// Structure to represent a node in the adjacency list
struct AdjListNode {
int dest;
struct AdjListNode* next;
};
// Structure to represent the graph
struct Graph {
int numVertices;
struct AdjListNode** adjLists;
};
// Function to create a new adjacency list node
struct AdjListNode* createNode(int dest) {
struct AdjListNode* newNode = (struct AdjListNode*)malloc(sizeof(struct
AdjListNode));
newNode->dest = dest;
newNode->next = NULL;
return newNode;
}
// Function to create a graph with 'numVertices' vertices
struct Graph* createGraph(int numVertices) {
struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph));
graph->numVertices = numVertices;
graph->adjLists = (struct AdjListNode**)malloc(numVertices *
sizeof(struct AdjListNode*));
for (int i = 0; i < numVertices; i++) {
graph->adjLists[i] = NULL; // Initialize each adjacency list as
empty
}
return graph;
8
Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
// Function to add an edge to an undirected graph
void addEdge(struct Graph* graph, int src, int dest) {
// Add edge from src to dest
struct AdjListNode* newNode = createNode(dest);
newNode->next = graph->adjLists[src];
graph->adjLists[src] = newNode;
// Add edge from dest to src (for undirected graph)
newNode = createNode(src);
newNode->next = graph->adjLists[dest];
graph->adjLists[dest] = newNode;
}
// Function to delete an edge from an undirected graph
void deleteEdge(struct Graph* graph, int src, int dest) {
// Delete from src's list
struct AdjListNode* current = graph->adjLists[src];
struct AdjListNode* prev = NULL;
while (current != NULL && current->dest != dest) {
prev = current;
current = current->next;
}
if (current != NULL) { // Edge found
if (prev == NULL) { // Node to be deleted is the head
graph->adjLists[src] = current->next;
} else {
prev->next = current->next;
}
free(current);
} else {
printf("Edge (%d, %d) not found.\n", src, dest);
}
// Delete from dest's list
current = graph->adjLists[dest];
prev = NULL;
while (current != NULL && current->dest != src) {
prev = current;
current = current->next;
}
if (current != NULL) { // Edge found
if (prev == NULL) { // Node to be deleted is the head
graph->adjLists[dest] = current->next;
} else {
prev->next = current->next;
}
free(current);
}
9
Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
// Function to print the adjacency list representation of the graph
void printGraph(struct Graph* graph) {
for (int v = 0; v < graph->numVertices; v++) {
struct AdjListNode* pCrawl = graph->adjLists[v];
printf("\n Adjacency list of vertex %d\n head ", v);
while (pCrawl) {
printf("-> %d", pCrawl->dest);
pCrawl = pCrawl->next;
}
printf("\n");
}
}
// Driver program to test the functions
int main() {
int numVertices = 5;
struct Graph* graph = createGraph(numVertices);
addEdge(graph, 0, 1);
addEdge(graph, 0, 4);
addEdge(graph, 1, 2);
addEdge(graph, 1, 3);
addEdge(graph, 1, 4);
addEdge(graph, 2, 3);
addEdge(graph, 3, 4);
printf("Graph before deletion:\n");
printGraph(graph);
deleteEdge(graph, 1, 4);
printf("\nGraph after deleting edge (1, 4):\n");
printGraph(graph);
deleteEdge(graph, 0, 2); // Attempt to delete a non-existent edge
printf("\nGraph after attempting to delete edge (0, 2):\n");
printGraph(graph);
// Free allocated memory (important for preventing memory leaks)
for (int i = 0; i < numVertices; i++) {
struct AdjListNode* current = graph->adjLists[i];
while (current != NULL) {
struct AdjListNode* temp = current;
current = current->next;
free(temp);
}
}
free(graph->adjLists);
free(graph);
return 0;
}
10
Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
Answer with graphic representation:
A vector has been used to implement the graph using adjacency list
representation. It is used to store the adjacency lists of all the vertices.
The vertex number is used as the index in this vector.
Example:
Below is a graph and its adjacency list representation:
If the edge between 1 and 4 has to be removed, then the above graph
and the adjacency list transforms to:
11
Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
The idea is to represent the graph as an array of vectors such that every
vector represents adjacency list of the vertex.
Adding an edge: Adding an edge is done by inserting both of the
vertices connected by that edge in each others list. For example, if an
edge between (u, v) has to be added, then u is stored in v's vector
list and v is stored in u's vector list. (push_back)
Deleting an edge: To delete edge between (u, v), u's adjacency
list is traversed until v is found and it is removed from it. The same
operation is performed for v.(erase)
Below is the implementation of the approach:
// C++ implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
// A utility function to add an edge in an
// undirected graph.
void addEdge(vector<int> adj[], int u, int v)
{
adj[u].push_back(v);
adj[v].push_back(u);
}
// A utility function to delete an edge in an
// undirected graph.
void delEdge(vector<int> adj[], int u, int v)
{
// Traversing through the first vector list
// and removing the second element from it
for (int i = 0; i < adj[u].size(); i++) {
if (adj[u][i] == v) {
adj[u].erase(adj[u].begin() + i);
break;
}
}
// Traversing through the second vector list
// and removing the first element from it
for (int i = 0; i < adj[v].size(); i++) {
12
Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
if (adj[v][i] == u) {
adj[v].erase(adj[v].begin() + i);
break;
}
}
}
// A utility function to print the adjacency list
// representation of graph
void printGraph(vector<int> adj[], int V)
{
for (int v = 0; v < V; ++v) {
cout << "vertex " << v << " ";
for (auto x : adj[v])
cout << "-> " << x;
printf("\n");
}
printf("\n");
}
// Driver code
int main()
{
int V = 5;
vector<int> adj[V];
// Adding edge as shown in the example figure
addEdge(adj, 0, 1);
addEdge(adj, 0, 4);
addEdge(adj, 1, 2);
addEdge(adj, 1, 3);
addEdge(adj, 1, 4);
addEdge(adj, 2, 3);
addEdge(adj, 3, 4);
// Printing adjacency matrix
printGraph(adj, V);
// Deleting edge (1, 4)
// as shown in the example figure
delEdge(adj, 1, 4);
// Printing adjacency matrix
printGraph(adj, V);
13
Sakshi Chakraborty
BCA_New
Course: MCSL-209 (Data Structures and Algorithms Lab)
Sakshi Chakraborty, BCA-IGNOU, B.S.-Digital Marketing & Data Analytics(DSEU)
Saurjendu Sahoo, Integrated B.Tech(Computer Science & Engineering), DSEU
[email protected], [email protected]
return 0;
}
Output:
vertex 0 -> 1-> 4
vertex 1 -> 0-> 2-> 3-> 4
vertex 2 -> 1-> 3
vertex 3 -> 1-> 2-> 4
vertex 4 -> 0-> 1-> 3
vertex 0 -> 1-> 4
vertex 1 -> 0-> 2-> 3
vertex 2 -> 1-> 3
vertex 3 -> 1-> 2-> 4
vertex 4 -> 0-> 3
Time Complexity: Removing an edge from adjacent list requires, on the
average time complexity will be O(|E| / |V|) , which may result in cubical
complexity for dense graphs to remove all edges.
Auxiliary Space: O(V) , here V is number of vertices.
14