DS Lab
DS Lab
DATA STRUCTURES
To emerge into excellence and premier institute, transforming individuals into highly
enlightenedprofessionals enriched with innovative skills entwined with intellectual, ethical
and human values.
MISSION OF THE INSTITUTE
M1: To Impart quality technical education to enhance knowledge and skills towards
employability, higher education and research.
M2: To Promote up gradation of teaching and research skills through quality infrastructure and
resources.
M3: To Enrich and elevate the rural education seekers, endow them with ethics, innovative
thinking and leadership qualities enabling them to utilize their technical skills and
competencies for the sustainable development of the Nation and mankind.
VISION OF THE DEPARTMENT
To become a Center of Excellence for highly competent and skilled Computer Science and
SoftwareEngineers with human and ethical values, to meet the challenges in the society.
MISSION OF THE DEPARTMENT
M1: Infrastructure and Curriculum Development: To produce excellent infrastructure and
innovative curriculum to prepare skilled and competent Software engineers.
M2: Skill Development: To Organize workshops, seminars, and hands-on training sessions to
equip students with the required skills and knowledge. Also emphasize the development of soft
skills like communication, leadership, teamwork and ethics.
M3: Research, Innovation and Collaboration: To Encourage students and faculty to engage in
ground-breaking research and innovative projects in association with Industry.
PROGRAM EDUCATIONAL OBJECTIVES (PEOs):
PEO1: Prospective Career: Exhibit knowledge and skills in the various domains of Computer
Science and Engineering for prospective careers in National and Global Industries.
PEO2: Higher Education: Be strong in fundamentals of Computer Science and Engineering
for successfully pursuing higher education and research in reputed institutions.
PEO3: Product Development: Apply their knowledge and innovative ideas to design and
develop products for real time problems, as per the needs of the society, government and
industries, and emerge as entrepreneurs.
PEO4: Teamwork & Life Long Learning: Be effective team member, exhibit leadership
abilities, professional ethics, communication skills, interpersonal skills and practice lifelong
learning.
PROGRAM SPECIFIC OUTCOMES (PSOS)
PSO 1: Ability to learn the applicability of various systems software elements for solving
designproblems.
PSO 2: Ability to apply their skills in the field of Web Designing, Cloud Computing,
MachineLearning, Artificial Intelligence and Internet of Things.
PROGRAM OUTCOMES
• Engineering Knowledge
• Problem Analysis
• Design/Development of Solutions
• Ethics
• Communication
• Life-long learning
ANNAMACHARYA INSTITUTE OF TECHNOLOGY & SCIENCES::KADAPA
(AUTONOMOUS)
(Approved by AICTE New Delhi & Affiliated to JNTUA,
Anantapuramu)Accredited by NAAC with ‘A’ grade, Bangalore
Course Objectives:
The course aims to strengthen the ability of the students to identify and apply the suitable data
structure for the given real-world problem. It enables them to gain knowledge in practical
applications of data structures.
CO1: Explain the role of linear data structures in organizing and accessing dataefficiently
in algorithms.
CO2: Design, implement, and apply linked lists for dynamic data storage,demonstrating
understanding of memory allocation.
CO4: Apply queue-based algorithms for efficient task scheduling and distinguish between
deques and priority queues and apply them appropriately to solve data management challenges.
CO5: Recognize scenarios where hashing is advantageous, and design hash-based solutions
forspecific problems and explain the role of non linear data structures in organization.
List of Experiments:
Experiment 10:Graphs
Textbooks:
Reference Books:
This course encompasses essential skills required for Understand the significance of linear data
structures in problem-solving and basic time/space complexity analysis.Create and manage
linked lists to efficiently organize and manipulate data, emphasizing memory
efficiency.Implement and apply stacks to manage program flow and solve problems involving
expression evaluation and backtracking.Utilize queues to model real-world scenarios, such as
process scheduling and breadth- first search algorithms and understand the versatility of deques
and prioritize data management using priority queues.Explore basic concepts of hashing and
apply it to solve problems requiring fast data retrieval and management.
COURSE OBJECTIVES
The course aims to strengthen the ability of the students to identify and apply the suitable data
structure for the given real-world problem. It enables them to gain knowledge in practical
applications of data structures.
COURSE OUTCOMES
Explain the role of linear data structures in organizing and accessing data efficiently in
algorithms.
Design, implement, and apply linked lists for dynamic data storage,demonstrating
understanding of memory allocation.
Develop programs using stacks to handle recursive algorithms,manage program states,
and solve related problems.
Apply queue-based algorithms for efficient task scheduling and distinguish between
deques and priority queues and apply them appropriately to solve data management
challenges.
Recognize scenarios where hashing is advantageous, and design hash-based solutions
forspecific problems and explain the role of non linear data structures in organization.
PRE-REQUISITES
CO-PO MAPPING
Life-long learning
Problem analysis
Conduct investigations of
Communication
Individualhand team
The engineer and the
Design/development of
problems
complex
Environment
sustainab
managem
Engineering
ent and
Project
finance
and its
knowledge
ilityE
c
s
t
i
solutions
society
work
P P P P P P P P P PO PO PS PS
COs PO1
O O O O O O O O O 10 1 O O
1 2 3 4 5 6 7 8 9 1 2 1 2
CO1 3 1 1 2 - - - 1 - - - - 1 1
CO2 3 2 2 2 - - - 1 - - - - 1 1
CO3 3 3 3 3 - - - 1 - 1 - - 1 1
CO4 3 3 3 3 - - - 1 1 - - - 1 1
CO5 3 2 2 2 2 - - 1 - - - - 1 1
Total 15 12 9 9 2 0 0 0 0 0 0 0 5 5
No. of Cos
mapping with 5 5 5 5 1 0 0 0 0 0 0 0 5 5
POs
Average 3.0 2.4 1.8 1.8 2.0 0.00 0.0 0.0 0.0 0.0 0.00 0.0 3.0 3.0
0 0 0 0 0 0 0 0 0 0 0 0
Round(Avera 3 2 2 2 - - - - - - - - 3 3
ge
)
DO’S & DON’TS
Do’s:
Remove your shoes or wear foot socks before you enter the lab.
Report any problems with the computer to the person in charge.
Always keep quiet. Be considerate to other lab users.
Read and understand how to carry out an activity thoroughly before coming to the
laboratory.
Shut down the computer properly.
Don’ts:
int main() {
int n,arr[MAX],i;
clrscr();
printf("Enter the number of elements in the array: ");
scanf("%d", &n);
printf("Enter the elements of the array:\n");
for (i = 0; i < n; i++)
scanf("%d", &arr[i]);
Output:
Enter the number of elements in the array: 5
Enter the elements of the array:
12 32 21 10 9
Original array: 12 32 21 10 9
Reversed array: 9 10 21 32 12
Result: Hence,the c program for reversing the array is successfully executed.
ii) C Programs to implement the Searching Techniques – Linear & Binary Search
AIM: To write a C Programs to implement the Searching Techniques – Linear & Binary Search
Description:
A linear search is the simplest approach employed to search for an element in a data set. It
examines each element until it finds a match, starting at the beginning of the data set, until the
end. The search is finished and terminated once the target element is located.Binary search
is an efficient algorithm for finding an item from a sorted list of items. It works by repeatedly
dividing in half the portion of the list that could contain the item, until you've narrowed down
the possible locations to just one.
Program:
#include <stdio.h>
#define MAX 100
// Linear search function
int linearSearch(int arr[], int n, int x) {
int i;
for (i = 0; i < n; i++) {
if (arr[i] == x) {
return i;
}
}
return -1;
}
int main() {
int n, x,arr[MAX],i;
int linear_result,binary_result;
clrscr();
printf("Enter number of elements in the array: ");
scanf("%d", &n);
printf("Enter %d sorted elements:\n", n);
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
int main() {
int arr[50],i,n;
clrscr();
printf("Enter the no.of elements\n");
scanf("%d",&n);
printf("Enter the list of elements\n");
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
printf("Original array: ");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
bubbleSort(arr, n);
Selection Sort
AIM: To write a C Programs to implement the Selection Sort Technique
Description:
In selection sort, the smallest value among the unsorted elements of the array is selected in
every pass and inserted to its appropriate position into the array. First, find the smallest element
of the array and place it on the first position. Then, find the second smallest element of the
array and place it on the second position. The process continues until we get the sorted array.
The array with n elements is sorted by using n-1 pass of selection sort algorithm.
Program:
void selectionSort(int arr[], int size) {
int minIndex, temp,i,j;
for (i = 0; i < size - 1; i++) {
minIndex = i;
for (j = i + 1; j < size; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// Swap the found minimum element with the first element
temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
int main() {
int arr[50],i,n;
clrscr();
printf("Enter the no.of elements\n");
scanf("%d",&n);
printf("Enter the list of elements\n");
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
printf("Original array: ");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
selectionSort(arr, n);
Insertion Sort
AIM: To write a C Programs to implement the Insertion Sort Technique
Description:
Insertion sort is one of the best sorting techniques. It is twice as fast as Bubble sort. In Insertion
sort the elements comparisons are as less as compared to bubble sort. In this comparison the
value until all prior elements are less than the compared values is not found. This means that
all the previous values are lesser than compared value. Insertion sort is good choice for small
values and for nearly sorted values.
Program:
#include <stdio.h>
int main() {
int arr[50],n,i;
clrscr();
printf("Enter the no.of elements\n");
scanf("%d",&n);
printf("Enter the list of elements\n");
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
insertionSort(arr, n);
Experiment- 2
Linked list Implementation
i) C Programs to Implement a singly linked list and perform insertion and deletion
operations.
AIM: To write a C Programs to implement a singly linked list and perform insertion and
deletion
Description:
A singly linked list is a type of linked list that is unidirectional, that is, it can be traversed in
only one direction from head to the last node . Each element in a linked list is called a node. A
single node contains data and a pointer to the next node which helps in maintaining the structure
of the list. Insertion into a singly linked list has two special cases .it’s insertion a new node
before the head node and after the end node. In any other case ,new node is inserted in the
middle of the list . Deleting a node from the list in three ways: delete from the beginning ,delete
from the middle,and delete from the end
Program:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
// Define the Node structure
struct Node {
int data;
struct Node* next;
};
// Function to create a new node
struct Node* createNode(int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// Function to insert a node at the beginning
void insertAtBeginning(struct Node** head, int data) {
struct Node* newnode = createNode(data);
newnode->next = *head;
*head = newnode;
printf("Inserted %d at beginning\n",data);
}
// Function to insert a node at the end
void insertAtEnd(struct Node** head, int data) {
struct Node* newnode = createNode(data);
struct Node* last;
if (*head == NULL) {
*head = newnode;
printf("Inserted %d at the first\n",data);
return;
}
last = *head;
while (last->next != NULL) {
last = last->next;
}
last->next = newnode;
printf("Inserted %d at the end\n",data);
}
// Function to delete the first node
void deleteFirstNode(struct Node** head) {
struct Node* temp;
if (*head == NULL) return;
temp = *head;
*head = temp->next;
free(temp);
printf("First Node deleted\n");
}
// Function to delete the last node
void deleteLastNode(struct Node** head) {
struct Node * temp;
if (*head == NULL) return;
if ((*head)->next == NULL) {
free(*head);
*head = NULL;
return;
}
temp = *head;
while (temp->next->next != NULL)
temp = temp->next;
free(temp->next);
temp->next = NULL;
printf("Last Node deleted\n");
}
// Function to print the linked list
void printList(struct Node* head) {
while (head != NULL) {
printf(" %d ", head->data);
head = head->next;
}
printf("\n");
}
int main() {
struct Node* head = NULL;
clrscr();
insertAtBeginning(&head, 7);
insertAtBeginning(&head, 1);
insertAtEnd(&head,6);
insertAtEnd(&head, 4);
insertAtEnd(&head,10);
printf("Created Linked list is: ");
printList(head);
deleteFirstNode(&head);
printf("Linked List after deleting first node: ");
printList(head);
deleteLastNode(&head);
printf("Linked List after deleting last node: ");
printList(head);
getche();
return 0;
}
Output:
Inserted 7 at beginning
Inserted 1 at beginning
Inserted 6 at the end
Inserted 4 at the end
Inserted 10 at the end
Created Linked list is: 1 7 6 4 10
First Node deleted
Linked List after deleting first node: 7 6 4 10
Last Node deleted
Linked List after deleting last node: 7 6 4
Result:
Hence, The program for implementing singly linked list and performing insertion and
deletion operations has been successfully executed.
return rest;
}
int main() {
struct Node* head = NULL;
clrscr();
insertAtEnd(&head, 1);
insertAtEnd(&head, 2);
insertAtEnd(&head, 3);
insertAtEnd(&head, 4);
insertAtEnd(&head, 5);
// Reverse iteratively
reverseIteratively(&head);
printf("Reversed List (Iterative): ");
printList(head);
if (current == NULL) {
printf("Value not found in the list.\n");
return;
}
previous->next = current->next;
free(current);
}
// Demonstrating deletion
deleteFirstNode(&head);
printf("After deleting the first node: ");
printList(head);
deleteNodeByValue(&head, 30);
printf("After deleting a node with value 30: ");
printList(head);
Experiment - 3
Linked List Applications
newnode->data = data;
newnode->next = NULL;
if (*head == NULL) {
*head = newnode;
return;
}
last->next = newnode;
}
int main() {
struct Node* head = NULL;
clrscr();
// Creating the list: 10->20->20->30->40->30->NULL
push(&head, 10);
push(&head, 20);
push(&head, 20);
push(&head, 30);
push(&head, 40);
push(&head, 30);
printf("Original linked list:\n");
printList(head);
removeDuplicates(head);
printf("Linked list after removing duplicates:\n");
printList(head);
getch();
return 0;
}
Output:
Original linked list:
10 20 20 30 40 30
Linked list after removing duplicates:
10 20 30 40
Result:
Hence , c program to detect and remove duplicates from a linked list is executed successfully.
ii) To Implement a linked list to represent polynomials and perform addition.
AIM: To Implement a linked list to represent polynomials and perform addition.
Description:
Polynomial addition in c programming is a fundamental operation in mathematics and
computer science, widely used in various applications such as signal processing, computer
graphics, and scientific simulations. We will do the polynomial addition using linked list in C
programming. When dealing with polynomials, it is essential to have an efficient and flexible
data structure to represent and perform operations on them. Linked lists provide an elegant
solution for efficiently handling polynomials due to their dynamic memory allocation and
straightforward implementation.
Some helpful Observations which will aid us in performing the Polynomial Addition using
Linked List in C are:
• We only added the coefficients of the like terms (terms having the same variables and
the same degree).
• The terms are placed in descending order by degree.
Program:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
// Node structure to store each term of a polynomial
struct Node {
int coeff;
int exp;
struct Node* next;
};
newnode->coeff = coeff;
newnode->exp = exp;
newnode->next = NULL;
// If the polynomial is empty, insert the new term as the first term
if (*poly == NULL) {
*poly = newnode;
} else {
// Move to the end of the polynomial
while (last->next != NULL) {
last = last->next;
}
// Add the new term at the end of the polynomial
last->next = newnode;
}
}
// Function to add two polynomials
struct Node* addPolynomials(struct Node* poly1, struct Node* poly2) {
struct Node* result = NULL;
while (poly1 != NULL && poly2 != NULL) {
// If the exponents are the same, add the coefficients
if (poly1->exp == poly2->exp) {
insertTerm(&result, poly1->coeff + poly2->coeff, poly1->exp);
poly1 = poly1->next;
poly2 = poly2->next;
}
// If poly1's exponent is greater, add poly1's term to the result
else if (poly1->exp > poly2->exp) {
insertTerm(&result, poly1->coeff, poly1->exp);
poly1 = poly1->next;
}
// If poly2's exponent is greater, add poly2's term to the result
else {
insertTerm(&result, poly2->coeff, poly2->exp);
poly2 = poly2->next;
}
}
// If there are remaining terms in poly1, add them to the result
while (poly1 != NULL) {
insertTerm(&result, poly1->coeff, poly1->exp);
poly1 = poly1->next;
}
// If there are remaining terms in poly2, add them to the result
while (poly2 != NULL) {
insertTerm(&result, poly2->coeff, poly2->exp);
poly2 = poly2->next;
}
return result;
}
// Function to print the polynomial
void printPolynomial(struct Node* head) {
while (head != NULL) {
printf("%dx^%d", head->coeff, head->exp);
head = head->next;
if (head != NULL)
printf(" + ");
}
printf("\n");
}
int main() {
struct Node* poly1 = NULL;
struct Node* poly2 = NULL;
struct Node* result = NULL;
clrscr();
// Insert terms into the first polynomial: 5x^2 + 4x^1 + 2
insertTerm(&poly1, 5, 3);
insertTerm(&poly1, 4, 2);
insertTerm(&poly1, 2, 1);
// Insert terms into the second polynomial: -5x^1 - 2
insertTerm(&poly2, -3, 2);
insertTerm(&poly2, 2, 1);
printf("Polynomial 1: ");
printPolynomial(poly1);
printf("Polynomial 2: ");
printPolynomial(poly2);
// Add the polynomials
result = addPolynomials(poly1, poly2);
printf("Resultant Polynomial: ");
printPolynomial(result);
getch();
return 0;
}
Output:
Polynomial 1: 5x^3 + 4x^2 + 2x^1
Polynomial 2: -3x^2 + 2x^1
Resultant Polynomial: 5x^3 + 1x^2 + 4x^1
Result:
Hence, a linked list to represent polynomials and perform addition has been implemented
successfully.
Description:
The dequeue represents Double Ended Queue. In the queue, the inclusion happens
from one end while the erasure happens from another end. The end at which the addition
happens is known as the backside while the end at which the erasure happensis known as front
end. Deque is a direct information structure in which the inclusion and cancellation tasks are
performed from the two finishes. We can say that deque is a summed up form of the line.
How about we take a gander at certain properties of deque. Deque can be utilized both as stack
and line as it permits the inclusion and cancellation procedure on the two finishes. In deque,
the inclusion and cancellation activity can be performed from one side. The stack adheres to
the LIFO rule in which both the addition and erasure can be performed distinctly from one end;
in this way, we reason that deque can be considered as a stack.
Program:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define MAX 10
int deque[MAX];
int front = -1, rear = -1;
Experiment-4
Double Linked List Implementation
i) Aim: Implement a doubly linked list and perform various operations to understand
it’s properties and applications.
Description: Doubly linked list is a complex type of linked list in which a node contains a
pointer to the previous as well as the next node in the sequence. Therefore, in a doubly linked
list, a node consists of three parts: node data, pointer to the next node in sequence (next pointer)
, pointer to the previous node (previous pointer). A doubly linked list containing three nodes
having numbers from 1 to 3 in their data part The prev part of the first node and the next part
of the last node will always contain null indicating end in each direction.
Program:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
// Node structure for a doubly linked list
struct Node {
int data;
struct Node* prev;
struct Node* next;
};
// Function to delete a node with given data from the doubly linked list
struct Node* deleteNode(struct Node* head, int data) {
if (head == NULL) {
printf("List is empty. Cannot delete.\n");
} else {
struct Node* current = head;
struct Node* prevNode = NULL;
while (current != NULL && current->data != data) {
prevNode = current;
current = current->next;
}
if (current == NULL) {
printf("Node with data %d not found.\n", data);
} else {
if (prevNode == NULL) {
head = current->next;
} else {
prevNode->next = current->next;
if (current->next != NULL) {
current->next->prev = prevNode;
}
}
free(current);
printf("Node with data %d deleted.\n", data);
}
}
return head;
}
// Function to traverse and display the doubly linked list
void displayList(struct Node* head) {
if (head == NULL) {
printf("List is empty.\n");
} else {
printf("Doubly linked list: ");
while (head != NULL) {
printf("%d ", head->data);
head = head->next;
}
printf("\n");
}
}
int main() {
struct Node* head = NULL;
clrscr();
// Inserting elements into the doubly linked list
head = insertAtBeginning(head, 10);
head = insertAtEnd(head, 20);
head = insertAtBeginning(head, 5);
head = insertAtEnd(head, 30);
displayList(head);
head = deleteNode(head, 20);
displayList(head);
getche();
return 0;
}
Output:
Inserted 10 at the beginning.
Inserted 20 at the end.
Inserted 5 at the beginning.
Inserted 30 at the end.
Doubly linked list: 5 10 20 30
Node with data 20 deleted.
Doubly linked list: 5 10 30
Result:
Hence, a doubly linked list and perform various operations to understand itsproperties and
applications is successfully implemented.
ii) Aim: To implement a circular linked list and perform insertion, deletion , and
traversal.
Description: Circular Linked List is a variation of Linked list in which the first element points
to the last element and the last element points to the first element. Both Singly Linked List and
Doubly Linked List can be made into a circular linked list. n singly linked list, the next pointer
of the last node points to the first node. In doubly linked list, the next pointer of the last node
points to the first node and the previous pointer of the first node points to the last node making
the circular in both directions.
• The last link's next points to the first link of the list in both cases of singly as well as
doubly linked list.
• The first link's previous points to the last of the list in case of doubly linked list.
Following are the important operations supported by a circular list.
• insert − Inserts an element at the start of the list.
• delete − Deletes an element from the start of the list.
• display − Displays the list.
Program:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
// Node structure for a circular linked list
struct Node {
int data;
struct Node* next;
};
// Function to create a new node
struct Node* createNode(int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("Memory allocation failed.\n");
exit(1);
}
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// Function to insert a node at the beginning of the circular linked list
struct Node* insertAtBeginning(struct Node* head, int data) {
struct Node* newNode = createNode(data);
if (head == NULL) {
head = newNode;
newNode->next = head; // Circular link to itself
printf("Inserted %d at the beginning.\n", data);
} else {
struct Node* temp = head;
while (temp->next != head) {
temp = temp->next;
}
temp->next = newNode;
newNode->next = head;
head = newNode;
printf("Inserted %d at the beginning.\n", data);
}
return head;
}
// Function to insert a node at the end of the circular linked list
struct Node* insertAtEnd(struct Node* head, int data) {
struct Node* newNode = createNode(data);
if (head == NULL) {
head = newNode;
newNode->next = head; // Circular link to itself
} else {
struct Node* temp = head;
while (temp->next != head) {
temp = temp->next;
}
temp->next = newNode;
newNode->next = head;
printf("Inserted %d at the end.\n", data);
}
return head;
}
// Function to delete a node with given data from the circular linked list
struct Node* deleteNode(struct Node* head, int data) {
if (head == NULL) {
printf("List is empty. Cannot delete.\n");
} else {
struct Node* temp = head;
struct Node* prevNode = NULL;
do {
if (temp->data == data) {
if (prevNode == NULL) { // If the node to be deleted is the head node
while (temp->next != head) {
temp = temp->next;
}
temp->next = head->next;
free(head);
head = temp->next;
break;
} else {
prevNode->next = temp->next;
free(temp);
break;
}
}
prevNode = temp;
temp = temp->next;
} while (temp != head);
if (temp == head) {
printf("Node with data %d not found.\n", data);
}
printf("Node with data %d deleted.\n", data);
}
return head;
}
// Function to traverse and display the circular linked list
void displayList(struct Node* head) {
if (head == NULL) {
printf("List is empty.\n");
} else {
struct Node* temp = head;
printf("Circular linked list: ");
do {
printf("%d ", temp->data);
temp = temp->next;
} while (temp != head);
printf("\n");
}
}
int main() {
struct Node* head = NULL;
clrscr();
// Inserting elements into the circular linked list
head = insertAtBeginning(head, 10);
head = insertAtEnd(head, 20);
head = insertAtBeginning(head, 5);
head = insertAtEnd(head, 30);
displayList(head);
head = deleteNode(head, 20);
displayList(head);
getche();
return 0;
}
Output:
Inserted 10 at the beginning
Inserted 20 at the end
Inserted 5 at the beginning
Inserted 30 at the end
Circular linked list: 5 10 20 30
Node with data 20 deleted
Circular linked list: 5 10 30
Result:
Hence, a circular linked list and perform insertion, deletion, and traversal is implemented
successfully.
Experiment- 5
Stack Operations
i) Aim: To Implement a stack using arrays
Description: A stack is a linear data structure in which the insertion of a new element and
removal of an existing element takes place at the same end represented as the top of the stack.
To implement the stack, it is required to maintain the pointer to the top of the stack, which is
the last element to be inserted because we can access the elements only on the top of the
stack.In an array-based implementation, the push operation is implemented by incrementing
the index of the top element and storing the new element at that index. The pop operation is
implemented by storing the element at the top, decrementing the index of the top element and
returning the value stored.
Program:
Stack using arrays:
#include <stdio.h>
#include <conio.h>
#define MAX_SIZE 10
// Structure to represent a stack
struct Stack {
int arr[MAX_SIZE];
int top;
};
// Function to initialize the stack
void initializeStack(struct Stack *stack) {
stack->top = -1;
}
// Function to check if the stack is full
int isFull(struct Stack *stack) {
return stack->top == MAX_SIZE - 1;
}
// Function to check if the stack is empty
int isEmpty(struct Stack *stack) {
return stack->top == -1;
}
// Function to push an element onto the stack
void push(struct Stack *stack, int value) {
if (isFull(stack)) {
printf("Stack overflow. Cannot push %d\n", value);
} else {
stack->arr[++stack->top] = value;
printf("Pushed %d onto the stack\n", value);
}
}
// Function to pop an element from the stack
int pop(struct Stack *stack) {
if (isEmpty(stack)) {
printf("Stack underflow. Cannot pop from an empty stack\n");
return -1; // Return a sentinel value for an empty stack
} else {
return stack->arr[stack->top--];
}
}
// Function to display the elements in the stack
void display(struct Stack *stack) {
int i;
if (isEmpty(stack)) {
printf("Stack is empty.\n");
} else {
for (i = 0; i <= stack->top; ++i) {
printf("%d ", stack->arr[i]);
}
printf("\n");
}
}
int main() {
struct Stack myStack;
int poppedValue;
clrscr();
initializeStack(&myStack);
// Push elements onto the stack
push(&myStack, 10);
push(&myStack, 20);
push(&myStack, 30);
push(&myStack, 40);
push(&myStack, 50);
// Display the stack
printf("Stack after pushes: ");
display(&myStack);
// Pop an element from the stack
poppedValue = pop(&myStack);
printf("Popped value: %d\n", poppedValue);
printf("Popped value: %d \n",pop(&myStack));
printf("Popped value: %d\n", pop(&myStack));
// Display the stack after pop
printf("Stack after pop: ");
display(&myStack);
getche();
return 0;
}
Output:
Pushed 10 onto the stack
Pushed 20 onto the stack
Pushed 30 onto the stack
Pushed 40 onto the stack
Pushed 50 onto the stack
Stack after pushes: 10 20 30 40 50
Popped value: 50
Popped value: 40
Popped value: 30
Stack after pop: 10 20
Result: Hence, a stack using arrays is implemented successfully.
Stack using Linked list:
Aim: To Implement a stack using linked lists.
Description: In a linked list-based implementation, the push operation is implemented by
creating a new node with the new element and setting the next pointer of the current top node
to the new node. The pop operation is implemented by setting the next pointer of the current
top node to the next node and returning the value of the current top node.
Program:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
// Structure to represent a node in the stack
struct Node {
int data;
struct Node* next;
};
// Structure to represent the stack
struct Stack {
struct Node* top;
};
// Function to initialize the stack
void initializeStack(struct Stack* stack) {
stack->top = NULL; // Initialize top to NULL to indicate an empty stack
}
// Function to check if the stack is empty
int isEmpty(struct Stack* stack) {
return stack->top == NULL;
}
// Function to push an element onto the stack
void push(struct Stack* stack, int element) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("Memory allocation failed! Cannot push %d onto the stack.\n", element);
return;
}
newNode->data = element;
newNode->next = stack->top;
stack->top = newNode;
// Stack structure
typedef struct {
int top;
int items[MAX];
} Stack;
// Function to initialize the stack
void initStack(Stack *s) {
s->top = -1;
}
// Check if the stack is empty
int isEmpty(Stack *s) {
return s->top == -1;
}
// Check if the stack is full
int isFull(Stack *s) {
return s->top == MAX - 1;
}
// Push an element onto the stack
void push(Stack *s, int value) {
if (isFull(s)) {
printf("Stack is full\n");
return;
}
s->items[++(s->top)] = value;
}
// Pop an element from the stack
int pop(Stack *s) {
if (isEmpty(s)) {
printf("Stack is empty\n");
return -1; // Returning -1 to indicate error
}
return s->items[(s->top)--];
}
// Function to evaluate postfix expression
int evaluatePostfix(char *exp) {
Stack s;
int i,val1,val2;
initStack(&s);
for (i = 0; exp[i]; ++i) {
// If the scanned character is an operand (number here),
// push it to the stack.
if (isdigit(exp[i])) {
push(&s, exp[i] - '0'); // Convert char to int
}
// If the scanned character is an operator, pop two
// elements from stack apply the operator
else {
val1 = pop(&s);
val2 = pop(&s);
switch (exp[i]) {
case '+': push(&s, val2 + val1); break;
case '-': push(&s, val2 - val1); break;
case '*': push(&s, val2 * val1); break;
case '/': push(&s, val2 / val1); break;
}
}
}
return pop(&s); // Return the result of the expression
}
int main() {
char exp[] = "231*+9-";
clrscr();
printf("postfix evaluation: %s = %d\n", exp, evaluatePostfix(exp));
getche();
return 0;
}
Output:
Postfix evaluation: 231*+9- = -4
Result:
Hence, a program to evaluate a postfix expression using a stack is successfully executed
iii) Aim: Implement a program to check for balanced parentheses using a stack.
Description: To check for balanced brackets in an expression using stack in C programming,
you need to traverse the expression and keep track of the opening and closing parentheses using
a stack data structure. If an opening parenthesis is encountered, it is pushed onto the stack, and
if a closing parenthesis is encountered, it is compared with the top element of the stack.If the
closing parenthesis matches the top element, the top element is popped, and the traversal
continues. If the closing parenthesis does not match the top element or there are no more
elements in the stack, the expression is considered unbalanced.
Program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define MAX 100
typedef struct {
int top;
char items[MAX];
} Stack;
void initStack(Stack *s) {
s->top = -1;
}
int isEmpty(Stack *s) {
return s->top == -1;
}
int isFull(Stack *s) {
return s->top == MAX - 1;
}
void push(Stack *s, char value) {
if (isFull(s)) {
printf("Stack is full\n");
return;
}
s->items[++(s->top)] = value;
}
char pop(Stack *s) {
if (isEmpty(s)) {
return -1; // Return -1 to indicate error/empty
}
return s->items[(s->top)--];
}
// Function to check if the characters are matching left and right parentheses
int isMatch(char character1, char character2) {
return (character1 == '(' && character2 == ')') ||
(character1 == '{' && character2 == '}') ||
(character1 == '[' && character2 == ']');
}
// Function to check if parentheses are balanced
int areParenthesesBalanced(char expression[]) {
Stack s;
int i;
initStack(&s);
for (i = 0; i < strlen(expression); i++) {
// If the character is an opening parenthesis, push it onto the stack
if (expression[i] == '(' || expression[i] == '{' || expression[i] == '[') {
push(&s, expression[i]);
} else if (expression[i] == ')' || expression[i] == '}' || expression[i] == ']') {
// If the stack is empty or parentheses do not match
if (isEmpty(&s) || !isMatch(pop(&s), expression[i])) {
return 0; // Not balanced
}
}
}
// If the stack is empty, parentheses are balanced
return isEmpty(&s);
}
int main() {
char expression[30];
clrscr();
printf("Input an expression in parentheses:");
scanf("%s",expression);
if (areParenthesesBalanced(expression))
printf("Balanced\n");
else
printf("Not Balanced\n");
getche();
return 0;
}
Output:
Input an expression in parentheses: ({}[])
Balanced
Result:
Hence, a program to check for balanced parentheses using a stack is successfully
executed.
Experiment – 6
Queue Operations
typedef struct {
int arr[MAX_SIZE];
int front, rear;
} Queue;
// Initialize the queue
void initialize(Queue *queue) {
queue->front = -1; // Initialize front
queue->rear = -1; // Initialize rear
}
// Check if the queue is empty
int isEmpty(Queue *queue) {
return (queue->front == -1 && queue->rear == -1);
}
// Check if the queue is full
int isFull(Queue *queue) {
return (queue->rear + 1) % MAX_SIZE == queue->front;
}
// Enqueue (add element to the queue)
void enqueue(Queue *queue, int value) {
if (isFull(queue)) {
printf("Queue is full! Cannot enqueue.\n");
return;
} else if (isEmpty(queue)) {
queue->front = 0; // If empty, set front to 0
}
queue->rear = (queue->rear + 1) % MAX_SIZE;
queue->arr[queue->rear] = value;
printf("Enqueued %d to the queue.\n", value);
}
// Dequeue (remove element from the queue)
int dequeue(Queue *queue) {
int dequeuedValue;
if (isEmpty(queue)) {
printf("Queue is empty! Cannot dequeue.\n");
return -1; // Return an error value
}
dequeuedValue = queue->arr[queue->front];
if (queue->front == queue->rear) {
// If only one element is present, reset front and rear
queue->front = -1;
queue->rear = -1;
} else {
queue->front = (queue->front + 1) % MAX_SIZE;
}
printf("Dequeued %d from the queue.\n", dequeuedValue);
return dequeuedValue;
}
// Get the front element of the queue
int front(Queue *queue) {
if (isEmpty(queue)) {
printf("Queue is empty!\n");
return -1;
}
return queue->arr[queue->front];
}
int main() {
Queue queue;
clrscr();
initialize(&queue);
enqueue(&queue, 10);
enqueue(&queue, 20);
enqueue(&queue, 30);
printf("Front element: %d\n", front(&queue)); // Output: 10
dequeue(&queue); // Output: Dequeued 10 from the queue.
printf("Front element after dequeue: %d\n", front(&queue)); // Output: 20
getche();
return 0;
}
Output:
Enqueued 10 to the queue
Enqueued 20 to the queue
Enqueued 30 to the queue
Front element: 10
Dequeued 10 from the queue
Front element after dequeue: 20
Result:
Hence, a Queue using arrays is implemented successfully.
if (isEmpty(queue)) {
queue->front = newNode;
} else {
queue->rear->next = newNode;
}
queue->rear = newNode;
printf("Enqueued %d to the queue.\n", value);
}
// Dequeue (remove element from the queue)
int dequeue(Queue* queue) {
int dequeuedValue;
struct Node* temp;
if (isEmpty(queue)) {
printf("Queue is empty! Cannot dequeue.\n");
return -1; // Return an error value
}
dequeuedValue = queue->front->data;
temp = queue->front;
queue->front = queue->front->next;
free(temp);
if (queue->front == NULL) {
queue->rear = NULL; // Adjust rear if queue becomes empty
}
printf("Dequeued %d from the queue.\n", dequeuedValue);
return dequeuedValue;
}
// Get the front element of the queue
int front(Queue* queue) {
if (isEmpty(queue)) {
printf("Queue is empty!\n");
return -1; // Return an error value
}
return queue->front->data;
}
int main() {
Queue queue;
clrscr();
initialize(&queue);
enqueue(&queue, 10);
enqueue(&queue, 20);
enqueue(&queue, 30);
printf("Front element: %d\n", front(&queue));
dequeue(&queue);
printf("Front element after dequeue: %d\n", front(&queue));
getche();
return 0;
}
Output:
Enqueued 10 to the queue
Enqueued 20 to the queue
Enqueued 30 to the queue
Front element: 10
Dequeued 10 from the queue
Front element after dequeue: 20
Result:
Hence, a Queue using linked lists is implemented successfully.
typedef struct {
PrintJob* front;
PrintJob* rear;
int count;
} Queue;
// Function to create a new print job node
PrintJob* createPrintJob(int id, const char* docName) {
PrintJob* newJob = (PrintJob*)malloc(sizeof(PrintJob));
if (newJob == NULL) {
printf("Error allocating memory.\n");
return NULL;
}
newJob->jobId = id;
strcpy(newJob->docName, docName);
newJob->next = NULL;
return newJob;
}
displayQueue(&printerQueue);
processedJob = dequeue(&printerQueue);
free(processedJob); // Free memory after processing
displayQueue(&printerQueue);
getch();
return 0;
}
Output:
Job 1 enqueued successfully.
Job 2 enqueued successfully.
Job 3 enqueued successfully.
Current Printer Queue:
Job ID: 1, Document: file1.pdf
Job ID: 2, Document: report.docx
Job ID: 3, Document: image.jpg
Job 1 dequeued.
Current Printer Queue:
Job ID: 2, Document: report.docx
Job ID: 3, Document: image.jpg
typedef struct {
int items[QUEUE_SIZE];
int front, rear;
} CircularQueue;
void initQueue(CircularQueue *q) {
q->front = -1;
q->rear = -1;
}
int isFull(CircularQueue *q) {
return (q->rear + 1) % QUEUE_SIZE == q->front;
}
int isEmpty(CircularQueue *q) {
return q->front == -1;
}
void enqueue(CircularQueue *q, int element) {
if (isFull(q)) {
printf("Queue is full!\n");
return;
}
if (isEmpty(q)) {
q->front = 0;
}
q->rear = (q->rear + 1) % QUEUE_SIZE;
q->items[q->rear] = element;
printf("Inserted -> %d\n", element);
}
int dequeue(CircularQueue *q) {
int element;
if (isEmpty(q)) {
printf("Queue is empty!\n");
return -1;
}
element = q->items[q->front];
if (q->front == q->rear) {
// Queue has only one element, so we reset the queue after removing it.
q->front = -1;
q->rear = -1;
} else {
q->front = (q->front + 1) % QUEUE_SIZE;
}
return element;
}
void printQueue(CircularQueue *q) {
int i;
if (isEmpty(q)) {
printf("Queue is empty!\n");
return;
}
printf("Queue elements: ");
i = q->front;
while (1) {
printf("%d ", q->items[i]);
if (i == q->rear)
break;
i = (i + 1) % QUEUE_SIZE;
}
printf("\n");
}
int main() {
CircularQueue q;
clrscr();
initQueue(&q);
enqueue(&q, 1);
enqueue(&q, 2);
enqueue(&q, 3);
enqueue(&q, 4);
enqueue(&q, 5);
// Trying to add an element should fail because the queue is full.
enqueue(&q, 6);
printQueue(&q);
printf("Dequeued: %d\n", dequeue(&q));
printf("Dequeued: %d\n", dequeue(&q));
printQueue(&q);
enqueue(&q, 6);
printQueue(&q);
getche();
return 0;
}
Output:
Inserted -> 1
Inserted -> 2
Inserted -> 3
Inserted -> 4
Inserted -> 5
Queue is full!
Queue elements: 1 2 3 4 5
Dequeued: 1
Dequeued: 2
Queue elements: 3 4 5
Inserted -> 6
Queue elements: 3 4 5 6
Result:
Hence, problems involving in circular queues are solved.
Experiment-7
Stack and Queue Applications
i. Aim: To Write a program using a stack to evaluate an infix expression and convert
it to postfix.
Description: The general mathematical way of representing algebraic expressions is to write
the operator between operands: Example: a + b. Such representation is called the Infix
representation. If we write the operator after the operands Example: a b +, it is called the Postfix
representation. It is also called the "Reverse Polish notation". Representing an algebraic
expression in postfix eliminates parentheses and the need of precedence. The evaluation
becomes simple. It is the ideal notation a computer uses to evaluate complex algebraic
expressions using stacks.
• An operator is printed after its operands in a postfix expression.
• In postfix notation, the infix expression 2+3 equals 23+.
Program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#define MAX 100
/*Evaluating an infix expression and converting it to a postfix
expression using a stack in C involves two main steps:
1.Conversion of an Infix expression to a Postfix expression
2.Evaluation of the Postfix expression*/
typedef struct {
int top;
char items[MAX];
} Stack;
while (!isEmpty(&s)) {
postfix[j++] = pop(&s);
}
postfix[j] = '\0';
}
int evaluatePostfix(char* postfix) {
Stack s;
int i;
initStack(&s);
for (i = 0; postfix[i]; i++) {
if (isOperand(postfix[i])) {
push(&s, postfix[i] - '0'); // Convert operand from char to int
} else {
int val1 = pop(&s);
int val2 = pop(&s);
switch (postfix[i]) {
case '+': push(&s, val2 + val1); break;
case '-': push(&s, val2 - val1); break;
case '*': push(&s, val2 * val1); break;
case '/': push(&s, val2 / val1); break;
}
}
}
return pop(&s);
}
int main() {
char infix[] = "3+(2*5)-9";
char postfix[MAX];
clrscr();
infixToPostfix(infix, postfix);
printf("Infix: %s\n", infix);
printf("Postfix: %s\n", postfix);
printf("Result: %d\n", evaluatePostfix(postfix));
getche();
return 0;
}
Output:
Infix: 3+(2*5)-9
Postfix: 325*+9-
Result: 4
Result:
Thus, a stack to evaluate an infix expression and convert it to postfix is executed
successfully.
ii. Aim: Create a program to determine whether a given string is a palindrome or not.
Description: A string is said to be palindrome if it remains the same on reading from both
ends. It means that when you reverse a given string, it should be the same as the original string.
For instance, the string ‘level’ is a palindrome because it remains the same when you read it
from the beginning to the end and vice versa.
Program:
#include <stdio.h>
#include <string.h>
#include <conio.h>
int isPalindrome(char str[]) {
int i = 0;
int j = strlen(str) - 1;
while (i < j) {
// Skip non-alphanumeric characters (optional)
while (!isalnum(str[i]) && i < j) i++;
while (!isalnum(str[j]) && i < j) j--;
// Check if the characters are different
if (tolower(str[i]) != tolower(str[j])) {
return 0; // Not a palindrome
}
i++;
j--;
}
return 1; // Is a palindrome
}
int main() {
char str[100];
clrscr();
printf("Enter a string: ");
fgets(str, sizeof(str), stdin); // Read string with spaces
str[strcspn(str, "\n")] = 0; // Remove trailing newline
if (isPalindrome(str)) {
printf("\"%s\" is a palindrome.\n", str);
} else {
printf("\"%s\" is not a palindrome.\n", str);
}
getche();
return 0;
}
Output:
Enter a string: Madam
“Madam” is a palindrome
Result:
Thus, a C program to determine whether a given string is a palindrome or notis executed
successfully.
iii. Aim: Implement a stack or queue to perform comparison and check for symmetry
Description:
A program to check if a given string or sequence is symmetric (a palindrome). This program
utilizes a stack data structure to push half of the sequence onto the stack and then compare it
with the second half of the sequence. If the stack contents match the corresponding characters
or elements of the sequence as they are popped, the sequence is symmetric. Otherwise, it is not.
Program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define MAX 100
typedef struct {
int top;
char items[MAX];
} Stack;
void initStack(Stack *s) {
s->top = -1;
}
int isFull(Stack *s) {
return s->top == (MAX - 1);
}
int isEmpty(Stack *s) {
return s->top == -1;
}
void push(Stack *s, char value) {
if (isFull(s)) {
printf("Stack is full.\n");
} else {
s->items[++(s->top)] = value;
}
}
char pop(Stack *s) {
if (isEmpty(s)) {
printf("Stack is empty.\n");
return -1; // Return a value that indicates the stack is empty
} else {
return s->items[(s->top)--];
}
}
int checkSymmetry(char str[]) {
int length = strlen(str);
Stack s;
int i,start;
initStack(&s);
// Push first half of str onto stack
for (i = 0; i < length / 2; i++) {
push(&s, str[i]);
}
// Start comparison from the middle of the string
start = (length % 2 == 0) ? (length / 2) : (length / 2 + 1);
for (i = start; i < length; i++) {
if (str[i] != pop(&s)) {
return 0; // Not symmetric
}
}
return 1; // Symmetric
}
int main() {
char str[MAX];
clrscr();
printf("Enter a string: ");
fgets(str, MAX, stdin); // Reading string input, including spaces
str[strcspn(str, "\n")] = 0; // Removing the newline character
if (checkSymmetry(str)) {
printf("The string \"%s\" is symmetric.\n", str);
} else {
printf("The string \"%s\" is not symmetric.\n", str);
}
getche();
return 0;
}
Output:
Enter a string: madam
The string “madam” is symmetric.
Result: The program has been successfully executed
Experiment – 8
Hashing
#define INITIAL_TABLE_SIZE 10
#define LOAD_FACTOR_THRESHOLD 0.7
struct KeyValuePair {
char key[50];
char value[50];
int isOccupied; // flag to mark if entry is active, helps in deletion
};
struct HashTable {
int size;
int itemCount;
struct KeyValuePair* table;
};
void insert(struct HashTable* hashTable, const char* key, const char* value) {
unsigned long index;
int attempt;
if (hashTable->itemCount >= LOAD_FACTOR_THRESHOLD * hashTable->size) {
resizeHashTable(hashTable);
}
Output:
Hash Table:
[0] -> (, )
[1] -> (Blue, #0000FF)
[2] -> (, )
[3] -> (, )
[4] -> (, )
[5] -> (, )
[6] -> (Green, #008000)
[7] -> (, )
[8] -> (Yellow, #FFFF00)
[9] -> (, )
[10] -> (Red, #ff0000)
[11] -> (, )
[12] -> (Orange, #FFA500)
[13] -> (, )
[14] -> (, )
[15] -> (, )
[16] -> (, )
[17] -> (, )
[18] -> (, )
[19] -> (, )
typedef struct {
CacheNode** buckets;
int capacity;
} Cache;
// Hash function
unsigned int hash(int key, int capacity) {
return (unsigned int)key % capacity;
}
Program:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
Experiment – 10
Graphs
struct node {
int vertex;
struct node* next;
};
struct Graph {
int totalVertices;
int* visited;
struct node** adjLists;
};
int main() {
int numVertices = 8; // Assuming vertices start from 0 to 7
struct Graph* graph = createGraph(numVertices);
clrscr();
addEdge(graph, 0, 4);
addEdge(graph, 0, 1);
addEdge(graph, 0, 2);
addEdge(graph, 2, 5);
addEdge(graph, 1, 6);
addEdge(graph, 1, 3);
printf("\nThe Adjacency List of the Graph is:");
displayGraph(graph);
printf("\nDFS traversal of the graph starting from vertex 0:\n");
DFS(graph, 0);
printf("\n");
getch();
return 0;
}
Output:
The Adjacency List of the Graph is:
0 => 2, 1, 4,
1 => 3, 6, 0,
2 => 5, 0,
3 => 1,
4 => 0,
5 => 2,
6 => 1,
7 =>
int main() {
int vertices, edges,i,startVertex;
int graph[MAX_VERTICES][MAX_VERTICES];
clrscr();
printf("Input the number of vertices: ");
scanf("%d", &vertices);
if (vertices <= 0 || vertices > MAX_VERTICES) {
printf("Invalid number of vertices. Exiting...\n");
return 1;
}
graph[MAX_VERTICES][MAX_VERTICES] = 0; // Initialize the adjacency matrix with
zeros
printf("Input the number of edges: ");
scanf("%d", &edges);
if (edges < 0 || edges > vertices * (vertices - 1) / 2) {
printf("Invalid number of edges. Exiting...\n");
return 1;
}
for (i = 0; i < edges; i++) {
int start, end;
printf("Input edge %d (start end): ", i + 1);
scanf("%d %d", &start, &end);
if (start < 0 || start >= vertices || end < 0 || end >= vertices) {
printf("Invalid vertices. Try again.\n");
i--;
continue;
}
addEdge(graph, start, end);
}
printf("Input the starting vertex for BFS traversal: ");
scanf("%d", &startVertex);
if (startVertex < 0 || startVertex >= vertices) {
printf("Invalid start vertex. Exiting...\n");
return 1;
}
BFS(graph, vertices, startVertex);
getch();
return 0;
}
Output:
Input the number of vertices: 5
Input the number of edges: 4
Input edge 1 (start end): 0 1
Input edge 2 (start end): 0 2
Input edge 3 (start end): 1 3
Input edge 4 (start end): 1 4
Input the starting vertex for BFS traversal: 0
BFS Traversal Order: 0 1 2 3 4
Result:
Hence, a BFS Traversal of a graph is implemented successfully.