0% found this document useful (0 votes)
44 views126 pages

C++ R

The document is a record for a practical course in Data Structures and Programming in C++ at Anna University, detailing various C++ programs and their implementations. It includes a list of experiments with specific aims, coding examples, and results for each program, covering topics such as constructors, dynamic memory allocation, inheritance, and algorithm implementations. Additionally, it contains a bonafide certificate and signatures from faculty members, indicating the work is part of the student's academic requirements.
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)
44 views126 pages

C++ R

The document is a record for a practical course in Data Structures and Programming in C++ at Anna University, detailing various C++ programs and their implementations. It includes a list of experiments with specific aims, coding examples, and results for each program, covering topics such as constructors, dynamic memory allocation, inheritance, and algorithm implementations. Additionally, it contains a bonafide certificate and signatures from faculty members, indicating the work is part of the student's academic requirements.
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/ 126

1

COLLEGE OF ENGINEERING GUINDY


ANNA UNIVERSITY
CHENNAI 600025

EC23C06 – DATA STRUCTURES AND PROGRAMMING


IN C++ - SEMESTER II
JANUARY 2025 - MAY 2025

RECORD
SUBMITTED BY
NAME :
REG NO :

In partial fulfilment for the award of the degree of


BACHELOR OF ENGINEERING
IN
ELECTRONICS AND COMMUNICATION
ENGINEERING
2
3

COLLEGE OF ENGINEERING GUINDY


ANNA UNIVERSITY
BONAFIDE CERTIFICATE
NAME:
DEPT:
REG NO:
It is certified that this is the Bonafide record of the work done by the
above-mentioned student in EC23C06 DATA STRUCTURES AND
PROGRAMMING IN C++ - SEMESTER-II (R-2023) during the period
JANUARY 2025 – MAY 2025

SIGNATURE SIGNATURE
LAB IN-CHARGE HEAD OF DEPARTMENT

SUBMITTED FOR THE PRACTICAL EXAM HELD ON ______________

SIGNATURE OF INTERNAL EXAMINER


4
5

S.No Date Title Page Marks Signature


No

1 13/02/25 C++ Program to Implement Constructors 9


and Destructors.

2 13/02/25 C++ Program to implement Member 13


Functions, Classes and Friend Functions.

3 13/02/25 C++ Program to Implement Dynamic 17


Memory Allocation and Overloading.

4 20/02/25 C++ Program to Implement Various 25


Inheritances.

5 13/03/25 C++ Program to Implement Virtual 43


Functions and Dynamic Binding.

6 20/03/25 C++ Program to implement various 47


operations on arrays.

7 20/03/25 C++ Program to Implement Various 57


Operations on Stacks using Array.

8 20/03/25 C++ Program to Implement Various 63


Operations on Queues using Array .

9 27/03/25 C++ Program to Evaluate the Infix 69


Expressions by converting into Prefix and
Postfix Expressions.
10 03/04/25 C++ Program to Implement Various 79
Operations on Linked Lists.

11 17/04/25 ⁠C++ program to implement binary tree 87


traversal and Graph Traversal Algorithm

12 17/04/24 ⁠C++ program to implement single source 97


shortest path algorithm and all pair shortest
path algorithm
6

13 24/04/25 ⁠C++ program to find the minimal spanning 105


tree for a graph.

14 24/04/25 C++ programs to implement linear search 111


and binary search algorithms.

15 24/04/25 C++ programs to implement insertion sort, 117


merge sort, Quick sort and
Heap sort algorithms.
7
8

FLOWCHART:

start

Create a class containing brand , year

Print default constructor with


default values

Create parameterized constructor with parameter


brand and year

Create copy constructor of parametrized constructor

Destructors of all these constructors are executed

stop
9

Ex No : 1 C++ Program to Implement Constructors and Destructors.


13/02/2025

Aim :
To write a C++ program to illustrate the use of Constructors and Destructors
Software Required:
VSCODE (C++ compiler)
Theory:
In C++, constructors and destructors are special member functions of a class. A
constructor is automatically called when an object is created and is used to initialize data
members. It has the same name as the class and no return type. Constructors can be default,
parameterized, or copy constructors. A destructor is automatically called when an object is
destroyed and is used to release resources. It has the same name as the class, preceded by a
tilde ~, and it also has no return type or parameters. These features help manage object lifecycle
efficiently.
Coding:
#include <iostream>
#include <string>
using namespace std
class Car {
private:
string brand;
int year;
public:
// Default constructor
Car() {
brand = "xxx";
year = 0;
cout << "Default constructor" << endl;
}
// Parameterized constructor
Car(string b, int y) {
cout << "Parameterized constructor" << endl;
10

Output:

Default constructor
Parameterized constructor
Copy constructor
Brand: xxx, Year: 0
Brand: Toyota, Year: 2020
Brand: Toyota, Year: 2020
Destructor called
Destructor called
Destructor called
11

brand = b;
year = y;
}
Car(const Car &c) {
brand = c.brand;
year = c.year;
cout << "Copy constructor" << endl;
}
// Destructor
~Car() {
cout << "Destructor called" << endl;
}
// Display function
void display() {
cout << "Brand: " << brand << ", Year: " << year << endl;
}
};
int main() {
Car c1; // Default constructor
Car c2("Toyota", 2020); // Parameterized constructor
Car c3 = c2; // Copy constructor
c1.display();
c2.display();
c3.display();
return 0;
}

Result:
Hence,the above program has been executed and verified successfully.
12

FLOWCHART:

start

Create a object b1

Read values of b1

Declare friend function doubleLength()

Double and print length value

stop
13

Ex No : 2 C++ Program to implement Member Functions, Classes and


13/02/2025 Friend Functions.

Aim:
To write a C++ program that demonstrates the use of classes, member functions, and friend
functions
Software Required:
VSCODE (C++ compiler)
Theory:
A class is a user-defined data type that groups variables and functions together.
Member functions are functions defined inside a class that operate on its objects and can
access private data. A friend function is a non-member function that is given special
permission to access the private and protected members of a class. It is declared using the friend
keyword inside the class.
Coding:
#include <iostream>
using namespace std;
class Box {
private:
int length;
public:
void setLength(int l) {
length = l;
}
void displayLength() {
cout << "Length = " << length << endl;
}
friend void doubleLength(Box b);
};
void doubleLength(Box b) {
cout << "Doubling the length" << endl;
cout << "Double Length = " << b.length * 2 << endl;
14

Output:
Length = 15
Doubling the length
Double Length = 30
15

}
int main() {
Box b1;
b1.setLength(15);
b1.displayLength();
doubleLength(b1);
return 0;
}

Result:
Hence,the above program has been executed and verified successfully.
16

FLOWCHART:
a)
start

Get size of array n

Dynamically allocate memory for n values

Input n values

Double and
Print
print
values
length value

stop
17

Ex No : 3 C++ Program to Implement Dynamic Memory Allocation and


13/02/2025 Overloading.

Aim :
a)To write a C++ program to dynamically allocate memory space using new operator
b) To write a C++ program to implement function overloading.
b)To write a C++ program to overload the addition(+) operator.
Software required :
VSCODE (C++ compiler)
Theory:
Dynamic memory allocation allows memory to be allocated during runtime using new
and released using delete, which helps manage memory efficiently when the size of data is not
known in advance. Function overloading enables multiple functions with the same name but
different parameters, improving code readability and flexibility. Operator overloading allows
built-in operators (like +, -, etc.) to be redefined for user-defined types such as classes, making
objects behave more like primitive types. Together, these features enhance program versatility,
reusability, and efficiency.
Coding:
a)
#include <iostream>
using namespace std;
int main() {
int size;
cout << "Enter the size of the array: ";
cin >> size;
int* arr = new int[size];
cout << "Enter " << size << " elements:\n";
for (int i = 0; i < size; i++) {
cin >> arr[i];
}
cout << "You entered: ";
18

Output:
10 10 10 10 10
Enter 5 values:
12332
12332

FLOWCHART:
b)
start

Declare functions with name area

Overload function ‘area’ with different datatype,


parameter

Calculate area for different datatypes

Print area values

stop
19

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


cout << arr[i] << " ";
}
cout << endl;

delete[] arr;
return 0;
}
b)
#include<iostream>
using namespace std;
int Area(int,int);
int Area(double,double);
double Area(double);
int main(){
int area;
double cir, a2;
area= Area(3,5);
cir=Area(2);
a2=Area(3.4,5.2);
cout<<"Area ="<<area;
cout<<"\nArea = "<<a2;
cout<<"\nArea of circle = "<<cir;
return 0;
}
int Area(int a, int b){
return a*b;
}
int Area(double a, double b){
return a*b;
20

Output:
Area =15
Area = 17
Area of circle = 12.56

FLOWCHART:
c)
start

Declare class comp with real and mg

Read values of c1 and c2

Operator ‘+’ is overloaded

Real and imaginary values are added

Print values

stop
21

}
double Area(double a){
double c;
c=3.14*a*a;
return c;
}
c)
#include <iostream>
using namespace std;
class comp{
int real,img;
public:
comp(int r=0, int i=0){
real =r;
img=i;
}
comp operator+(comp &c2){
comp a;
a.real= real+ c2.real;
a.img = img +c2.img;
return a;
}
void print(){
cout<<real<<" +i"<<img <<endl;
}
};
int main(){
comp c1(1,2), c2(3,4), c3;
c3= c1+c2;
c3.print();
22

Output:
4 +i6
23

return 0;
}

Result :
Hence,the above programs have been executed and verified successfully.
24

FLOWCHART:
a)
start

Declare a base class ‘Sports’ with data members

Declare a derived class ‘football’ from base class


‘Sports’

Print all the details

stop
25

Ex No : 4 C++ Program to Implement Various Inheritances.


20/02/2025

Aim :
a)To write a C++ program to illustrate single inheritance
b)To write a C++ program to illustrate multiple inheritance
c)To write a C++ program to illustrate multilevel inheritance
d)To write a C++ program to illustrate hierarchical inheritance
e)To write a C++ program to illustrate hybrid inheritance
Software Required:
VSCODE (C++ compiler)
Theory:
Inheritance is an object-oriented programming feature that allows a class (called the
derived or child class) to inherit properties and behaviors from another class (called the base
or parent class). The main types of inheritance include single inheritance, where one class
inherits from one base class; multiple inheritance, where a class inherits from two or more
base classes; multilevel inheritance, where a class is derived from another derived class;
hierarchical inheritance, where multiple classes inherit from a single base class; and hybrid
inheritance, which is a combination of two or more types. Inheritance promotes code
reusability, modularity, and helps organize complex systems into simpler class structures.
Coding:
a)
#include <iostream>
using namespace std;

class Sports {
protected:
int players;
string mode;
int duration;
};

class football : public Sports {


26

Output:
No. of players: 11
Mode: outdoor
Duration (mins): 90
Bootmodel: Adidas
League: laliga
27

string bootmodel;
string league;

public:
football(int players, int b, string c, string boot, string l) {
this->players = players;
mode = c;
duration = b;
bootmodel = boot;
league = l;
}

void disp() {
cout << "No. of players: " << players << endl;
cout << "Mode: " << mode << endl;
cout << "Duration (mins): " << duration << endl;
cout << "Bootmodel: " << bootmodel << endl;
cout << "League: " << league << endl;
}
};

int main() {
football F1(11, 90, "outdoor", "Adidas", "laliga");
F1.disp();
return 0;
}

b)
#include <iostream>
using namespace std;
28

FLOWCHART:
b)

start

Declare a base class ‘India’ and another base class


‘China’

Declare a derived class ‘curryrice’ from base


classes ‘India’ and ‘China’

Print ingredients

stop
29

class India {
protected:
string species;
};

class China {
public:
string rice;
int kg;
string oil;
float ltr;
};

class curryrice : public India, public China {


string plate;
public:
curryrice(string s, int k, string r, string o, float l, string pl) {
species = s;
kg = k;
rice = r;
oil = o;
ltr = l;
plate = pl;
}

void disp() {
cout << "Spice: " << species << endl;
cout << "Kg: " << kg << endl;
cout << "Rice Type: " << rice << endl;
30

Output:
Spice: Pepper
Kg: 2
Rice Type: Sticky rice
Oil: flax
Litres of oil: 0.5
Plate type: China

FLOWCHART:

c)

start

Declare a base class ‘India’ with data memebers

Declare a derived class ‘Kollywood from base


classes ‘Movie’

Declare a derived class ‘Leo’ from derived


class‘Kollywood’

Print all details of the movie

stop
31

cout << "Oil: " << oil << endl;


cout << "Litres of oil: " << ltr << endl;
cout << "Plate type: " << plate << endl;
}
};

int main() {
curryrice c1("Pepper", 2, "Sticky rice", "flax", 0.5, "China");
c1.disp();
return 0;
}
c)
#include <iostream>
using namespace std;

class Movie {
protected:
int year;
int duration;
};

class Kollywood : public Movie {


protected:
int songs;
};

class Leo : public Kollywood {


string name;
string hero;
string heroine;
32

Output:
Movie name: Leo
Year of release: 2023
Duration (mins): 185
No. of songs: 2
Actor: Vijay
Actress: Trisha
33

public:
Leo(int a, string c, int b, int s, string h, string h0) {
year = a;
name = c;
duration = b;
songs = s;
hero = h;
heroine = h0;
}

void disp() {
cout << "Movie name: " << name << endl;
cout << "Year of release: " << year << endl;
cout << "Duration (mins): " << duration << endl;
cout << "No. of songs: " << songs << endl;
cout << "Actor: " << hero << endl;
cout << "Actress: " << heroine << endl;
}
};

int main() {
Leo l(2023, "Leo", 185, 2, "Vijay", "Trisha");
l.disp();
return 0;
}
d)
#include <iostream>
using namespace std;

class Vehicle {
34

FLOWCHART:
d)

start

Declare a base class ‘Vehicle’ with data memebers

Declare derived classes ‘Car’ and ‘eBike’ from


base class ‘Vehicle’

Print all details of car and


ebike

stop
35

protected:
string price;
string brand;
};

class Car : public Vehicle {


string tire;
int hp;

public:
Car(string a, int h, string brd, string te) {
price = a;
hp = h;
brand = brd;
tire = te;
}

void disp() {
cout << "Price: ₹" << price << endl;
cout << "Brand name: " << brand << endl;
cout << "Tire model: " << tire << endl;
cout << "Horsepower: " << hp << " HP" << endl;
}
};

class eBike : public Vehicle {


int charge;
int range;
36

Output:
Price: ₹10,00,000
Brand name: BMW
Tire model: Goodyear
Horsepower: 300 HP

Price: ₹1,30,000
Brand name: OLA
Charging Time: 6 hrs
Range: 190 Km
37

public:
eBike(string a, int h, string brd, int ce) {
price = a;
range = h;
brand = brd;
charge = ce;
}

void disp() {
cout << "Price: ₹" << price << endl;
cout << "Brand name: " << brand << endl;
cout << "Charging Time: " << charge << " hrs" << endl;
cout << "Range: " << range << " Km" << endl;
}
};

int main() {
Car c1("10,00,000", 300, "BMW", "Goodyear");
eBike b1("1,30,000", 190, "OLA", 6);

c1.disp();
cout<<endl;
b1.disp();

return 0;
}
e)
#include <iostream>
using namespace std;
class Person {
38

FLOWCHART:
e)

start

Declare a base class ‘Person’ with data memebers

Declare derived classes ‘Academics and ‘Sports’


from base class ‘Person’

Declare a derived class ‘Result’ from ‘Academics’


and ‘Sports’

Print all details of student

stop
39

protected:
string name;
int id;
public:
void setPerson(string n, int i) {
name = n;
id = i;
}
void displayPerson() {
cout << "Name: " << name << endl;
cout << "ID: " << id << endl;
}
};
class Academics : virtual public Person {
protected:
float academicMarks;
public:
void setAcademicMarks(float m) {
academicMarks = m;
}
void displayAcademics() {
cout << "Academic Marks: " << academicMarks << "%" << endl;
}
};
class Sports: virtual public Person {
protected:
float sportsScore;

public:
void setSportsScore(float s) {
40

Output:
----- Student Result -----
Name: Alice
ID: 101
Academic Marks: 85.5%
Sports Score: 92%
Overall Performance: 88.75%
41

sportsScore = s;
}
void displaySports() {
cout << "Sports Score: " << sportsScore << "%" << endl;
}
};
class Result : public Academics, public Sports {
public:
void displayResult() {
cout << "----- Student Result -----" << endl;
displayPerson();
displayAcademics();
displaySports();
float total = (academicMarks + sportsScore) / 2;
cout << "Overall Performance: " << total << "%" << endl;
}
};
int main() {
Result student;
student.setPerson("Alice", 101);
student.setAcademicMarks(85.5);
student.setSportsScore(92.0);
student.displayResult();
return 0;
}

Result :
Hence,the above programs have been executed and verified successfully
42

FLOWCHART:

start

Declare a base class

Define virtual function ‘car’ and virtual destructor

Declare a derived class ‘Bmw’

Override car() function

Initialize Base class pointer with the address of


derived object

Calls Derived class car() due to dynamic binding

Derived class destrutor executed first, then base


class destructor

stop
43

Ex No : 5 C++ Program to Implement Virtual Functions and Dynamic


13/03/2025 Binding.

Aim :
To write a C++ program to demonstrate the use of virtual functions and dynamic binding.
Software Required :
VSCODE (C++ compiler)
Theory:
Virtual functions enable runtime polymorphism by allowing a base class pointer to
call functions in derived classes dynamically at runtime. When a function is declared as virtual
in the base class and overridden in the derived class, the decision of which function to execute
is made during program execution — a process known as dynamic binding or late binding.
This ensures that the correct version of the function is called based on the actual object type,
not the pointer type. Virtual functions are essential in implementing flexible and extensible
programs using inheritance and polymorphism.
Coding:
#include <iostream>
using namespace std;
class Base {
public:
virtual void car() {
cout << "Bought a car" << endl;
}
virtual ~Base() {
cout << "Sold a car" << endl;
}
};
class Bmw : public Base {
public:
void car() override {
cout << "Buy a BMW" << endl;
44

Output:
Buy a BMW
Sell the BMW
Sold a car
45

}
~Bmw() {
cout << "Sell the BMW" << endl;
}
};
int main() {
Base* c1;
Bmw obj;
c1 = &obj;
c1->car();
return 0;
}

Result :
Hence,the above programs have been executed and verified successfully.
46

Algorithm:
1. Start
2. Create an array and input the number of elements (n)
3. Input n elements into the array
4. Repeat until user selects Exit:
a. Show menu with choices: Display, Insert, Delete, Search, Update, Exit
b. Get user's choice
c. If Display, print all elements in the array
d. If Insert, input position and value, shift elements, insert value, increase n
e. If Delete, input position, shift elements left, decrease n
f. If Search, input value, check each element, print position if found
g. If Update, input position and new value, update that element
5. Print “Exiting...” and stop
47

Ex No : 6 C++ Program to Implement Various Operations on Arrays .


20/03/2025

Aim :
To write a C++ program that implements various operations on arrays such as
insertion, deletion, traversal, searching, and updating using a menu-driven approach.
Software Required :
VSCODE (C++ compiler)
Theory:
Arrays are used to store multiple values of the same data type in contiguous memory
locations, allowing efficient access and manipulation of elements. Various operations can be
performed on arrays, such as insertion, deletion, traversal, searching, and updating. Insertion
involves adding a new element at a specific position, which requires shifting subsequent
elements to the right. Deletion removes an element from a specific index by shifting the
remaining elements to the left. Traversal is the process of accessing each element, typically
using loops. Searching can be done through linear or binary methods, depending on whether
the array is sorted, while updating allows modification of a value at a particular index.
Coding:
#include <iostream>
using namespace std;

const int SIZE = 100;

void display(int arr[], int n) {


cout << "Array elements: ";
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
cout << endl;
}

void insert(int arr[], int &n, int pos, int val) {


if (n >= SIZE) {
cout << "Array is full!\n";
48
49

return;
}
if (pos < 0 || pos > n) {
cout << "Invalid position!\n";
return;
}
for (int i = n; i > pos; i--)
arr[i] = arr[i - 1];
arr[pos] = val;
n++;
cout << "Element inserted.\n";
}

void deleteElement(int arr[], int &n, int pos) {


if (pos < 0 || pos >= n) {
cout << "Invalid position!\n";
return;
}
for (int i = pos; i < n - 1; i++)
arr[i] = arr[i + 1];
n--;
cout << "Element deleted.\n";
}

void search(int arr[], int n, int val) {


for (int i = 0; i < n; i++) {
if (arr[i] == val) {
cout << "Element found at position " << i << endl;
return;
}
50
51

}
cout << "Element not found.\n";
}

void update(int arr[], int n, int pos, int val) {


if (pos < 0 || pos >= n) {
cout << "Invalid position!\n";
return;
}
arr[pos] = val;
cout << "Element updated.\n";
}

int main() {
int arr[SIZE], n = 0, choice, val, pos;

cout << "Enter number of elements: ";


cin >> n;
cout << "Enter elements:\n";
for (int i = 0; i < n; i++)
cin >> arr[i];

do {
cout << "\nMenu:\n";
cout << "1. Display\n2. Insert\n3. Delete\n4. Search\n5. Update\n6. Exit\n";
cout << "Enter your choice: ";
cin >> choice;

switch (choice) {
case 1:
52

Output:
Enter number of elements: 5
Enter elements:
10 20 30 40 50

Menu:
1. Display
2. Insert
3. Delete
4. Search
5. Update
6. Exit
Enter your choice: 1
Array elements: 10 20 30 40 50

Enter your choice: 2


Enter position and value to insert: 2 25
Element inserted.

Enter your choice: 1


Array elements: 10 20 25 30 40 50

Enter your choice: 3


Enter position to delete: 4
Element deleted.

Enter your choice: 1


Array elements: 10 20 25 30 50

Enter your choice:4


53

display(arr, n);
break;
case 2:
cout << "Enter position and value to insert: ";
cin >> pos >> val;
insert(arr, n, pos, val);
break;
case 3:
cout << "Enter position to delete: ";
cin >> pos;
deleteElement(arr, n, pos);
break;
case 4:
cout << "Enter value to search: ";
cin >> val;
search(arr, n, val);
break;
case 5:
cout << "Enter position and new value to update: ";
cin >> pos >> val;
update(arr, n, pos, val);
break;
case 6:
cout << "Exiting...\n";
break;
default:
cout << "Invalid choice!\n";
}
} while (choice != 6);
54

Enter value to search: 30


Element found at position 3

Enter your choice: 4


Enter value to search: 100
Element not found.

Enter your choice: 5


Enter position and new value to update: 1 99
Element updated.

Enter your choice: 1


Array elements: 10 99 25 30 50

Enter your choice: 6


Exiting...
55

return 0;
}

Result:
Hence,the above programs have been executed and verified successfully.
56

Algorithm:
1. Start and initialize an empty stack with top set to -1.
2. For each push operation, check if the stack is full; if not, increment top, insert the
value, and display a message.
3. Push values 10, 20, and 30 using the push operation.
4. To display the stack, check if it's empty; if not, print elements from top to bottom.
5. Show current stack elements using the display function.
6. To peek, check if the stack is empty; if not, print the top element.
7. Use peek to display the current top element.
8. For each pop, check if the stack is empty; if not, print the top element and
decrement top.
9. Pop one element and display the stack.
10. Pop two more elements to empty the stack.
11. Attempt another pop and display "Stack Underflow" since the stack is empty.
12. End the program.
57

Ex No : 7 C++ Program to Implement Various Operations on Stacks


20/03/2025 using Array.

Aim :
To write a C++ program to implement various operations on Stacks such as push, pop
and peek operations using Arrays.
Software Required:
VSCODE(C++ compiler)
Theory:
A stack is a linear data structure that works on the Last In First Out (LIFO) principle. It
can be implemented using arrays in C++ with a variable top to track the top element. Basic
operations include push (to insert), pop (to remove), peek (to view the top), and display (to
print all elements). Stack overflow occurs when inserting into a full stack, and underflow
occurs when removing from an empty stack. This implementation is simple and efficient when
the stack size is fixed.
Coding:
#include <iostream>
using namespace std;
#define SIZE 100
class Stack {
int arr[SIZE];
int top;
public:
Stack() {
top = -1;
}
void push(int value) {
if (top >= SIZE - 1) {
cout << "Stack Overflow!" << endl;
} else {
top++;
58
59

arr[top] = value;
cout << value << " pushed to stack." << endl;
}
}
void pop() {
if (top < 0) {
cout << "Stack Underflow!" << endl;
} else {
cout << "Popped element: " << arr[top] << endl;
top--;
}
}
void peek() {
if (top < 0) {
cout << "Stack is empty!" << endl;
} else {
cout << "Top element: " << arr[top] << endl;
}
}
void display() {
if (top < 0) {
cout << "Stack is empty!" << endl;
} else {
cout << "Stack elements (top to bottom): ";
for (int i = top; i >= 0; i--)
cout << arr[i] << " ";
cout << endl;
}
}
};
60

Output:
10 pushed to stack.
20 pushed to stack.
30 pushed to stack.
Stack elements (top to bottom): 30 20 10
Top element: 30
Popped element: 30
Stack elements (top to bottom): 20 10
Popped element: 20
Popped element: 10
Stack Underflow!
61

int main() {
Stack s;
s.push(10);
s.push(20);
s.push(30);
s.display();
s.peek();
s.pop();
s.display();
s.pop();
s.pop();
s.pop();
return 0;
}

Result :
Hence,the above programs have been executed and verified successfully
62

Algorithm:
1. Start the program and initialize front and rear to -1.
2. Enqueue 10, 20, and 30 by checking for overflow, setting front if needed,
incrementing rear, and inserting each value.
3. Display the queue if not empty by printing elements from front to rear.
4. Peek by checking if the queue is empty and printing the front element.
5. Dequeue once by checking for underflow, printing the front element, and
incrementing front.
6. Display the queue to show remaining elements.
7. Dequeue twice more to empty the queue, printing each element.
8. Attempt one more dequeue, detect underflow, and display an error message.
9. End the program.
63

Ex No : 8 C++ Program to Implement Various Operations on Queues


20/03/2025 using Arrays.

Aim :
To write a C++ program to implement various operations on Queues such as enqueue,
dequeue, peek and display operations using Arrays.
Software Required:
VSCODE (C++ compiler)
Theory:
A queue is a linear data structure that works on the First In First Out (FIFO) principle.
It can be implemented using arrays in C++ with two variables, front and rear, to track the
positions of elements. Basic operations include enqueue (to insert at the rear), dequeue (to
remove from the front), peek (to view the front element), and display (to print all elements).
Queue overflow occurs when inserting into a full queue, and underflow occurs when removing
from an empty queue. This implementation is simple and efficient when the queue size is fixed.
Coding:
#include <iostream>
using namespace std;
#define SIZE 100

class Queue {
int arr[SIZE];
int front, rear;

public:
Queue() {
front = -1;
rear = -1;
}

void enqueue(int value) {


if (rear >= SIZE - 1) {
64

Output:
10 enqueued to queue.
20 enqueued to queue.
30 enqueued to queue.
Queue elements (front to rear): 10 20 30
Front element: 10
Dequeued element: 10
Queue elements (front to rear): 20 30
Dequeued element: 20
Dequeued element: 30
Queue Underflow!
65

cout << "Queue Overflow!" << endl;


} else {
if (front == -1) front = 0;
rear++;
arr[rear] = value;
cout << value << " enqueued to queue." << endl;
}
}

void dequeue() {
if (front == -1 || front > rear) {
cout << "Queue Underflow!" << endl;
} else {
cout << "Dequeued element: " << arr[front] << endl;
front++;
}
}

void peek() {
if (front == -1 || front > rear) {
cout << "Queue is empty!" << endl;
} else {
cout << "Front element: " << arr[front] << endl;
}
}

void display() {
if (front == -1 || front > rear) {
cout << "Queue is empty!" << endl;
} else {
66
67

cout << "Queue elements (front to rear): ";


for (int i = front; i <= rear; i++)
cout << arr[i] << " ";
cout << endl;
}
}
};

int main() {
Queue q;
q.enqueue(10);
q.enqueue(20);
q.enqueue(30);
q.display();
q.peek();
q.dequeue();
q.display();
q.dequeue();
q.dequeue();
q.dequeue();
return 0;
}

Result :
Hence,the above programs have been executed and verified successfully.
68

Algorithm:
1. Start the program and take an infix expression as input from the user.
2. Convert infix to postfix:
a. Scan each character:
– If it's a digit, append it to the result.
– If it's '(', push to stack.
– If it's ')', pop and append from stack until '(' is found.
– If it's an operator, pop operators of higher or equal precedence and then push
current operator.
b. After scanning, pop all remaining operators to result.
3. Convert infix to prefix:
a. Reverse the infix string.
b. Swap '(' with ')' and vice versa.
c. Apply the same infix-to-postfix logic.
d. Reverse the result to get prefix.
4. Evaluate postfix expression:
a. Scan from left to right.
b. Push operands to stack.
c. On encountering an operator, pop two values, apply the operation, and push
result.
5. Evaluate prefix expression:
a. Scan from right to left.
b. Push operands to stack.
c. On encountering an operator, pop two values, apply the operation, and push
result.
6. Display postfix and prefix expressions and their evaluations.
7. End the program.
69

Ex No : 9 C++ Program to Evaluate the Infix Expressions by converting


27/03/2025 into Prefix and Postfix Expressions.

Aim :
To write a C++ program to evaluate the infix expressions by converting into Prefix
and Postfix expressions.
Software Required:
VSCODE (C++ compiler)
Theory:
Infix expressions are commonly used in mathematics, where operators appear between
operands (e.g., A + B). However, they are not efficient for computers to evaluate directly due
to the need to handle operator precedence and parentheses. To simplify evaluation, infix
expressions are first converted into postfix (Reverse Polish Notation) or prefix (Polish
Notation) form.
In postfix expressions, operators follow their operands (e.g., AB+). Conversion involves
scanning the infix expression left to right, using a stack to manage operators and precedence
rules. Similarly, prefix expressions place operators before operands (e.g., +AB). Prefix
conversion is done by reversing the infix expression, swapping brackets, converting to postfix,
and then reversing the result.
Once converted, both postfix and prefix expressions are easy to evaluate using a stack. For
postfix, scan from left to right; for prefix, scan from right to left. Operands are pushed onto the
stack, and on encountering an operator, the required number of operands are popped, the
operation is performed, and the result is pushed back. The final value in the stack is the result
of the expression.

Coding:
#include <iostream>
#include <stack>
#include <algorithm>
#include <cctype>
using namespace std;
int precedence(char op) {
if(op == '+'||op == '-') return 1;
if(op == '*'||op == '/') return 2;
return 0;
70
71

}
int applyOp(int a, int b, char op) {
switch(op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
}
return 0;
}
string infixToPostfix(string s) {
stack<char> st;
string result;

for(char ch : s) {
72
73

if(isdigit(ch))
result += ch;
else if(ch == '(')
st.push(ch);
else if(ch == ')') {
while(!st.empty() && st.top() != '(') {
result += st.top();
st.pop();
}
st.pop();
} else {
while(!st.empty() && precedence(st.top()) >= precedence(ch)) {
result += st.top();
st.pop();
}
st.push(ch);
}
}
while(!st.empty()) {
result += st.top();
st.pop();
}
return result;
}
string infixToPrefix(string s) {
reverse(s.begin(), s.end());

for(int i = 0; i < s.length(); i++) {


if(s[i] == '(') s[i] = ')';
else if(s[i] == ')') s[i] = '(';
74
75

}
string postfix = infixToPostfix(s);
reverse(postfix.begin(), postfix.end());
return postfix;
}
int evaluatePostfix(string expr) {
stack<int> st;
for(char ch : expr) {
if(isdigit(ch))
st.push(ch - '0');
else {
int b = st.top(); st.pop();
int a = st.top(); st.pop();
st.push(applyOp(a, b, ch));
}
}
return st.top();
}
int evaluatePrefix(string expr) {
stack<int> st;
for(int i = expr.length() - 1; i >= 0; i--) {
char ch = expr[i];
if(isdigit(ch))
st.push(ch - '0');
else {
int a = st.top(); st.pop();
int b = st.top(); st.pop();
st.push(applyOp(a, b, ch));
}
}
76

Output:
Enter infix expression : 6+2*3-4
Postfix: 623*+4-
Prefix: -+6*234
Postfix Evaluation: 8
Prefix Evaluation: 8
77

return st.top();
}

int main() {
string infix;
cout << "Enter infix expression : ";
cin >> infix;

string postfix = infixToPostfix(infix);


string prefix = infixToPrefix(infix);

cout << "Postfix: " << postfix << endl;


cout << "Prefix: " << prefix << endl;
cout << "Postfix Evaluation: " << evaluatePostfix(postfix) << endl;
cout << "Prefix Evaluation: " << evaluatePrefix(prefix) << endl;

return 0;
}

Result :
Hence,the above programs have been executed and verified successfully.
78

Algorithm:
1. Start the program and define a Node class with data and next pointer.
2. Define a LinkedList class with head initialized to NULL.
3. To insert at end, create a new node and link it after the last node.
4. To insert at front, create a new node and point it to current head, then update head.
5. To delete a node, search for the value, unlink it, and free memory.
6. To display, traverse from head and print each node until NULL.
7. To search, traverse the list and compare each node’s data.
8. In main(), perform operations like insertions, deletion, display, and search.
9. End the program.
79

Ex No : 10 C++ Program to Implement Various Operations on Linked


03/04/2025 Lists

Aim :
To write a C++ program to implement various Operations on Linked lists such as
insertion, deletion, traversal and search.
Software Required:
VSCODE(C++ compiler)
Theory:
A linked list is a dynamic data structure where each node contains data and a pointer to
the next node. This program implements a singly linked list in C++ with basic operations:
inserting at the front and end, deleting a node by value, searching for a value, and displaying
the list. It uses a Node class for individual elements and a LinkedList class to manage
operations using the head pointer. Unlike arrays, linked lists allow efficient insertion and
deletion without shifting elements.
Coding:
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* next;

Node(int value) {
data = value;
next = nullptr;
}
};
class LinkedList {
private:
Node* head;
80
81

public:
LinkedList() {
head = nullptr;
}
void insertEnd(int value) {
Node* newNode = new Node(value);
if (!head) {
head = newNode;
} else {
Node* temp = head;
while (temp->next)
temp = temp->next;
temp->next = newNode;
}
cout << value << " inserted at end.\n";
}
void insertFront(int value) {
Node* newNode = new Node(value);
newNode->next = head;
head = newNode;
cout << value << " inserted at front.\n";
}
void deleteNode(int value) {
if (!head) {
cout << "List is empty.\n";
return;
}
if (head->data == value) {
Node* toDelete = head;
head =
82
83

delete toDelete;
cout << value << " deleted from list.\n";
return;
}
Node* temp = head;
while (temp->next && temp->next->data != value)
temp = temp->next;

if (temp->next) {
Node* toDelete = temp->next;
temp->next = temp->next->next;
delete toDelete;
cout << value << " deleted from list.\n";
} else {
cout << value << " not found in list.\n";
}
}
void display() {
if (!head) {
cout << "List is empty.\n";
return;
}
Node* temp = head;
cout << "Linked List: ";
while (temp) {
cout << temp->data << " -> ";
temp = temp->next;
}
cout << "NULL\n";
}
84

Output:
10 inserted at end.
20 inserted at end.
5 inserted at front.
Linked List: 5 -> 10 -> 20 -> NULL
20 found in list.
10 deleted from list.
Linked List: 5 -> 20 -> NULL
10 not found in list.
85

void search(int value) {


Node* temp = head;
while (temp) {
if (temp->data == value) {
cout << value << " found in list.\n";
return;
}
temp = temp->next;
}
cout << value << " not found in list.\n";
}
};
int main() {
LinkedList list;
list.insertEnd(10);
list.insertEnd(20);
list.insertFront(5);
list.display();
list.search(20);
list.deleteNode(10);
list.display();
list.search(10);
return 0;
}

Result :
Hence,the above programs have been executed and verified successfully.
86

Algorithm:
a)
1. Define a Node structure with data, left, and right pointers.
2. Implement addnode(data) to create and return a new node.
3. Write recursive functions:
o preorder() → Root, Left, Right
o inorder() → Left, Root, Right
o postorder() → Left, Right, Root
4. In main(), create the root node using addnode(1).
5. Add child nodes to build the binary tree structure.
6. Call and print results of preorder(), inorder(), and postorder() on the root.
7. End the program.

b)
1. Define a graph class with vertex count and adjacency list.
2. In addEdge(u, v), connect both u → v and v → u.
3. In BFS(start), use a queue to visit nodes level by level.
4. In DFS(start), use recursion to visit nodes depth-wise.
5. In main(), create a graph with 6 nodes.
6. Add edges: (0-1), (0-2), (1-3), (2-4), (3-5), (4-5).
7. Call BFS(0) and print nodes in BFS order.
8. Call DFS(0) and print nodes in DFS order.
9. End.
87

Ex No: 11 C++ Program to Implement Binary Tree Traversal and


17/04/2025 Graph Traversal Algorithm

Aim :
To write a C++ program to implement the following:
a) Binary Tree Traversal
b) Graph Traversal(
Software Required:
VSCODE(C++ compiler)
Theory:
In preorder traversal, the root node is visited first, followed by the left subtree, and
then the right subtree. It is commonly used to copy trees or evaluate prefix expressions.
In inorder traversal, the left subtree is visited first, then the root, and finally the right
subtree. This traversal is especially useful in binary search trees as it gives nodes in sorted
order.
In postorder traversal, the left and right subtrees are visited before the root. It is often
used for deleting trees or evaluating postfix expressions.
Breadth-First Search (BFS) explores nodes level by level using a queue. It starts at a
given node and visits all its neighbours before going deeper. BFS is useful for finding the
shortest path in an unweighted graph.
Depth-First Search (DFS) explores as far as possible along one path before
backtracking. It uses recursion or a stack. DFS is helpful for checking connectivity, solving
puzzles, and detecting cycles in graphs.
Coding:
a)
#include<iostream>
using namespace std;
struct Node {
int data;
Node* left;
Node* right;
};
Node* addnode(int data) {
88

Output:
a)
Preorder
1
2
23
6
3
4
Inorder
23
2
6
1
4
3
Postorder
23
6
2
4
3
1
89

Node* newnode = new Node();


newnode->data = data;
newnode->left = newnode->right = nullptr;
return newnode;
}
void preorder(Node* root) {
if (root == nullptr) return;
cout << root->data << endl;
preorder(root->left);
preorder(root->right);
}
void inorder(Node* root) {
if (root == nullptr) return;
inorder(root->left);
cout << root->data << endl;
inorder(root->right);
}
void postorder(Node* root) {
if (root == nullptr) return;
postorder(root->left);
postorder(root->right);
cout << root->data << endl;
}
int main() {
Node* root = addnode(1);
root->left = addnode(2);
root->right = addnode(3);
root->left->right = addnode(6);
root->left->left = addnode(23);
root->right->left = addnode(4);
90
91

cout << "Preorder" << endl;


preorder(root);
cout << "Inorder" << endl;
inorder(root);
cout << "Postorder" << endl;
postorder(root);
return 0;
}
b)
#include<iostream>
#include<queue>
#include <vector>
using namespace std;
class graph{
int v;
vector<vector<int>> adj;
public:
graph(int a){
v=a;
adj.resize(v);
}
void addEdge(int u, int v){
adj[u].push_back(v);
adj[v].push_back(u);
}
void BFS(int start){
vector<bool> visited(v,false);
queue<int> q;
visited[start]=true;
q.push(start);
92
93

cout <<"Breadth First Search: "<<endl;


while(!q.empty()){
int node = q.front();
q.pop();
cout << node << " ";
for( int neighbour : adj[node] ){
if(!visited[neighbour]){
visited[neighbour]=true;
q.push(neighbour);
}
}
}
cout<<endl;
}
void DFS(int start){
vector<bool> visited(v,false);
cout<<"Depth First Search: "<<endl;
rec(start,visited);
}
private:
void rec(int node, vector<bool>& visited ){
visited[node]=true;
cout<<node<<" ";
for(int child: adj[node]){
while(!visited[child]){
rec(child, visited);
}
}
}
};
94

Output:
b)
Breadth First Search:
012345
Depth First Search:
013542
95

int main(){
graph g(6);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 3);
g.addEdge(2, 4);
g.addEdge(3, 5);
g.addEdge(4, 5);
g.BFS(0);
g.DFS(0);
}

Result :
Hence,the above programs have been executed and verified successfully.
96

Algorithm:
a)
1. Define a graph as an adjacency list with edge weights using vector<pair<int,int>>.
2. Create a distance[] array and initialize all distances to INF, except the source node to
0.
3. Use a min-heap priority queue to process nodes by shortest distance.
4. For each node, check all neighbors and update their distances if a shorter path is
found.
5. Push updated neighbors into the queue for further processing.
6. After the loop, print shortest distances from the source to all other nodes.
7. In main(), build a graph with 5 nodes and weighted edges.
8. Call sssp(0) to compute shortest paths from node 0.
9. End.
b)
1. Define a 2D matrix dist[i][j] representing shortest distance from node i to j, initially
using direct edge weights.
2. Set dist[i][i] = 0 for all nodes (distance to itself is zero).
3. Run 3 nested loops with k, i, j to check if path i → k → j is shorter than direct i → j.
4. If dist[i][k] + dist[k][j] < dist[i][j], update dist[i][j].
5. After completion, dist[i][j] contains the shortest distance from every node i to every
node j.
6. In main(), build the graph by assigning weights to valid edges, leaving others as INF.
7. Call floyd() to compute all pairs shortest paths.
8. Print the final distance matrix.
97

Ex No : 12 C++ Program to Implement single source shortest path


17/04/2025 algorithm and all pair shortest path algorithm.

Aim :
a) To write a C++ program to implement Single Source shortest path algorithm.
b) To write a C++ program to implement All pair shortest path algorithm.
Software Required:
VSCODE(C++compiler)
Theory:
The Single Source Shortest Path (SSSP) algorithm finds the shortest paths from a given
source node to all other nodes in a weighted graph. A commonly used algorithm for this is
Dijkstra’s Algorithm, which works efficiently with non-negative edge weights. It uses a priority
queue to always explore the nearest unvisited node and updates the shortest known distances
to its neighbors. This greedy approach ensures that once a node’s shortest path is found, it is
final.
The All Pairs Shortest Path (APSP) algorithm computes the shortest paths between every pair
of nodes in a graph. The Floyd-Warshall Algorithm is a classic solution for this, using dynamic
programming. It repeatedly updates a distance matrix by checking if going through an
intermediate node offers a shorter path between two nodes. It works on both directed and
undirected graphs, with positive or negative weights, as long as there are no negative cycles.
Coding:
a) #include <iostream>
#include <queue>
#include <vector>
#include <climits>
#define INF INT_MAX
using namespace std;
void sssp(int start, vector<vector<pair<int,int>>> &graph, int num){
vector<int> distance(num, INF);
distance[start]=0;
priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>> pq;
pq.push({0,start});
while(!pq.empty()){
98

Output:
a)
Shortest distance from node 0 to :
Node 0 : 0
Node 1 : 2
Node 2 : 3
Node 3 : 9
Node 4 : 6
99

int dist= pq.top().first;


int node= pq.top().second;
pq.pop();
for(auto neighbour: graph[node]){
int nextnode= neighbour.first;
int weight= neighbour.second;
if(distance[node]+weight< distance[nextnode]){
distance[nextnode]=distance[node]+weight;
pq.push({distance[nextnode],nextnode});
}
}
}
cout<<"Shortest distance from node "<< start<< " to :\n"<<endl;
for(int i=0;i<num;i++ ){
cout<<"Node "<<i<<" : ";
if(distance[i]==INF)
cout<<"Unreachable"<<endl;
else
cout<<distance[i]<<endl;
}

int main(){
int numnodes=5;
vector<vector<pair<int,int>>> graph(numnodes);
graph[0].push_back({1, 2});
graph[0].push_back({2, 4});
graph[1].push_back({2, 1});
graph[1].push_back({3, 7});
100
101

graph[2].push_back({4, 3});
graph[3].push_back({4, 1});
sssp(0,graph,numnodes);
return 0;
}
b)
#include <iostream>
#include <vector>
#include<climits>
#define INF INT_MAX
using namespace std;
void floyd(vector<vector<int>>& dist, int n){
int i,j,k;
for(k=0;k<n;k++){
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(dist[i][k]<INF && dist[k][j]<INF)
dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
}
}
}
}
int main(){
int n =4;
vector<vector<int>> dist(n, vector<int>(n, INF));
for(int i=0;i<n;i++){
dist[i][i]=0;
}
dist[0][1] = 3;
dist[0][2] = 10;
102

Output:
b)
Shortest distances between all pairs:
0123
00346
17013
26902
34780
103

dist[1][2] = 1;
dist[2][3] = 2;
dist[3][0] = 4;
floyd(dist, n);
cout << "Shortest distances between all pairs:\n";
cout<<" 0 1 2 3"<<endl;
for (int i = 0; i < n; ++i) {
cout<<i<<" ";
for (int j = 0; j < n; ++j) {
if (dist[i][j] == INF)
cout << "INF ";
else
cout << dist[i][j] << " ";
}
cout << endl;
}
return 0;
}

Result :
Hence,the above programs have been executed and verified successfully.
104

Algorithm:
1. Create a structure Edge to store two nodes and a weight for each edge.
2. Store all graph edges in a vector and sort them by weight (smallest first).
3. Initialize a Disjoint Set Union (DSU) to keep track of connected components.
4. For each sorted edge, check if the two vertices are in different sets using
find().
5. If they are, add the edge to the MST and unite the sets using unite().
6. Accumulate the edge weights to compute total MST cost.
7. After processing all edges, print the selected MST edges and the total weight.
8. The MST will have exactly V-1 edges if the graph is connected.
105

Ex No : 13 C++ Program to find the minimal spanning tree for a graph.


24/04/2025

Aim:
To write a C++ program to find the minimal Spanning tree for a graph.
Software Required:
VSCODE(C++ compiler)
Theory:
A Minimum Spanning Tree (MST) is a subset of the edges of a connected, weighted
graph that connects all the vertices with minimum total edge weight and no cycles. Among
several algorithms, Kruskal’s Algorithm is commonly used, which works by sorting all edges
by weight and adding the smallest edge that doesn’t form a cycle, until all vertices are
connected.
Kruskal's algorithm uses the Disjoint Set Union (DSU) or Union-Find structure to efficiently
detect cycles while adding edges. The MST always has exactly V - 1 edges for a graph with V
vertices. This algorithm works well for sparse graphs and has a time complexity of O(E log E)
due to edge sorting.
Coding:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Edge{
int u,v,weight;
};
bool compare(Edge a,Edge b){
return a.weight<b.weight;
}
class Disjoint{
vector<int> parent, rank;
public:
Disjoint(int v){
parent.resize(v);
106

Output:
Minimum Spanning Tree edges:
3-4:2
2-3:4
0-3:5
0 - 1 : 10
Total weight of MST: 21
107

rank.resize(v,0);
for(int i=0; i<v;i++)
parent[i]=i;
}
int find(int x){
if(parent[x]!=x)
parent[x]= find(parent[x]);
return parent[x];
}
bool unite(int u,int v){
int rootu=find(u);
int rootv=find(v);
if(rootu==rootv) return false;
if(rank[rootu]>rank[rootv])
parent[rootv]=rootu;
else if(rank[rootv]<rank[rootu])
parent[rootu]=rootv;
else{
parent[rootu]=rootv;
rank[rootv++];
}
return true;
}
};
int main(){
vector<Edge> edges;
int v=5;
edges={
{0 ,1,10},
{0, 2, 6},
108
109

{0 ,3, 5},
{1, 3 ,15},
{2 ,3, 4},
{1 ,2, 25},
{3, 4, 2}};
sort(edges.begin(),edges.end(),compare);
vector<Edge> mst;
Disjoint d(v);
int total=0;
for(Edge e: edges){
if (d.unite(e.u,e.v))
{
mst.push_back(e);
total+=e.weight;
}
}
cout << "\nMinimum Spanning Tree edges:\n";
for(Edge e : mst) {
cout << e.u << " - " << e.v << " : " << e.weight << endl;
}

cout << "Total weight of MST: " << total << endl;
return 0;
}

Result :
Hence,the above programs have been executed and verified successfully.
110

Algorithm:
a)
1. Start at the first element of the array.
2. Compare the current element with the target value.
3. If it matches, return the current index.
4. If it doesn't match, move to the next element.
5. Repeat until the end of the array.
6. If no match is found, return -1.
b)
1. Start with the entire sorted array.
2. Find the middle element.
3. If it matches the target, return the middle index.
4. If the target is smaller, repeat the search in the left half.
5. If the target is larger, repeat the search in the right half.
6. Continue until the element is found or the search space is empty.
7. If not found, return -1.
111

Ex No : 14 C++ Programs to implement linear search and binary search


24/04/2025 algorithms.

Aim:
To write a C++ program to implement (a)linear search and (b)binary search.
Software Required:
VSCODE(C++ compiler)
Theory:
Linear Search is a simple search algorithm that sequentially checks each element of
the array or list until the target element is found or the list ends. It does not require the array to
be sorted and works on any kind of data. Although easy to implement, it is not efficient for
large datasets, with a time complexity of O(n) where n is the number of elements.
Binary Search, on the other hand, is a much faster search algorithm but requires the
input array to be sorted. It works by repeatedly dividing the search interval in half: comparing
the middle element to the target, and deciding whether to search the left or right half. This
divide-and-conquer approach results in a time complexity of O(log n), making it significantly
faster than linear search for large sorted data.
Coding:
a)
#include<iostream>
using namespace std;
int linearSearch(int arr[], int n, int target) {
for (int i = 0; i < n; i++) {
if (arr[i] == target) {
return i;
}
}
return -1;
}
int main() {
int arr[] = {5, 2, 9, 1, 5, 6};
112

Output:
a) Element found at index: 0
b) Element found at index: 2
113

int target = 5;
int n = sizeof(arr)/sizeof(arr[0]);
int result = linearSearch(arr, n, target);
if (result != -1)
cout << "Element found at index: " << result << endl;
else
cout << "Element not found" << endl;
return 0;
}
b)
#include<iostream>
using namespace std;
int binarySearch(int arr[], int n, int target) {
int low = 0, high = n - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == target) return mid;
if (arr[mid] > target) high = mid - 1;
else low = mid + 1;
}
return -1;
}
int main() {
int arr[] = {1, 2, 5, 5, 6, 9};
int target = 5;
int n = sizeof(arr)/sizeof(arr[0]);
int result = binarySearch(arr, n, target);
if (result != -1)
cout << "Element found at index: " << result << endl;
else
114
115

cout << "Element not found" << endl;


return 0;
}

Result :
Hence,the above programs have been executed and verified successfully.
116

Algorithm:
a)
1. Start from the second element in the array.
2. Compare it with elements before it and shift larger elements one position to the right.
3. Insert the current element into its correct position.
4. Repeat for all elements until the array is sorted.
b)
1. Divide the array into two halves.
2. Recursively sort each half.
3. Merge the two sorted halves into one sorted array.
4. Repeat until the entire array is merged and sorted.
c)
1. Select a pivot element from the array.
2. Partition the array such that elements less than pivot go left, and greater go right.
3. Recursively apply the same process to the left and right subarrays.
4. Repeat until all subarrays are sorted.
d)
1. Build a max-heap from the array.
2. Swap the root (maximum) element with the last element.
3. Reduce heap size and heapify the root again.
4. Repeat until the heap size is reduced to one and the array is sorted.
117

Ex No : 15 C++ Programs to implement insertion sort, merge sort, quick


24/04/2025 sort and heap sort algorithms.

Aim:
To write a C++ program to implement the following:
a) Insertion sort
b) Merge sort
c) Quick sort
d) Heap sort
Software Required:
VSCODE(C++ compiler)
Theory:
Insertion Sort is a simple comparison-based sorting algorithm that builds the final
sorted array one element at a time. It works by taking one element from the unsorted part and
inserting it into the correct position in the sorted part. This process is repeated until all elements
are sorted. Insertion sort is efficient for small datasets or nearly sorted data and works in-place
with O(1) auxiliary space. However, its time complexity is O(n²) in the worst case, making it
less suitable for large datasets.
Merge Sort is a divide-and-conquer algorithm that divides the input array into two
halves, recursively sorts them, and then merges the sorted halves. This merging process ensures
that the final array is sorted. The key advantage of merge sort is its consistent time complexity
of O(n log n) for best, worst, and average cases. However, it requires additional memory space
proportional to the array size (O(n)) due to the temporary arrays used during the merge process.
Merge sort is stable and well-suited for sorting linked lists and large datasets.
Quick Sort is an efficient and widely-used divide-and-conquer sorting algorithm. It
works by selecting a ‘pivot’ element and partitioning the array such that elements smaller than
the pivot are on the left and those greater are on the right. The process is then applied
recursively to the subarrays. Quick sort has an average-case time complexity of O(n log n), but
it can degrade to O(n²) in the worst case if poor pivot choices are made. Despite this, it is often
faster in practice than other O(n log n) algorithms and works in-place with O(log n) auxiliary
space.
Heap Sort is a comparison-based sorting technique based on a binary heap data
structure. It first builds a max-heap from the input data, then repeatedly extracts the maximum
element from the heap and places it at the end of the array. This process continues until the
heap is empty and the array is sorted. Heap sort has a time complexity of O(n log n) for all
cases and requires only a constant amount of extra space (O(1)). Although it is not stable, heap
sort is very efficient for large data sets and does not require recursion.

Coding:
118

Output:
a)
Original array:
13
32
26
9
35
18
The elements are:
9
13
18
26
32
35
119

a)#include<iostream>
#include<vector>
using namespace std;
void insertion(vector<int>&arr){
int n=arr.size();
for(int i=0;i<n;i++){
int key=arr[i];
int j=i-1;
while(j>=0 && arr[j]>key){
arr[j+1]=arr[j];
j--;
}
arr[j+1]=key;
}
}
int main(){
vector<int>arr ={13,32,26,9,35,18};
vector<int>inserted =arr;
insertion(inserted);
cout<<"Original array: "<<endl;
for(int i=0;i<arr.size();i++){
cout<<"\t"<<arr[i] <<endl;
}
cout<<"The elements are: "<<endl;
for(int i=0;i<arr.size();i++){
cout<<"\t"<<inserted[i] <<endl;
}
return 0;
}
120

Output:
b) 1 2 5 5 6 9
c) 1 5 7 8 9 10
d) 1 3 4 5 10
121

b)
#include <iostream>
using namespace std;
void merge(int arr[], int l, int m, int r) {
int n1 = m - l + 1, n2 = r - m;
int L[n1], R[n2];
for (int i = 0; i < n1; i++) L[i] = arr[l + i];
for (int i = 0; i < n2; i++) R[i] = arr[m + 1 + i];
int i = 0, j = 0, k = l;
while (i < n1 && j < n2)
arr[k++] = (L[i] <= R[j]) ? L[i++] : R[j++];
while (i < n1) arr[k++] = L[i++];
while (j < n2) arr[k++] = R[j++];
}

void mergeSort(int arr[], int l, int r) {


if (l < r) {
int m = l + (r - l) / 2;
mergeSort(arr, l, m);
mergeSort(arr, m+1, r);
merge(arr, l, m, r);
}
}

int main() {
int arr[] = {5, 2, 9, 1, 5, 6};
int n = sizeof(arr)/sizeof(arr[0]);
mergeSort(arr, 0, n - 1);
for (int i = 0; i < n; i++) cout << arr[i] << " ";
}
122
123

c)
#include <iostream>
using namespace std;
int partition(int arr[], int low, int high) {
int pivot = arr[high], i = low - 1;
for (int j = low; j < high; j++)
if (arr[j] < pivot) swap(arr[++i], arr[j]);
swap(arr[i + 1], arr[high]);
return i + 1;
}
void quickSort(int arr[], int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
int main() {
int arr[] = {10, 7, 8, 9, 1, 5};
int n = sizeof(arr)/sizeof(arr[0]);
quickSort(arr, 0, n - 1);
for (int i = 0; i < n; i++) cout << arr[i] << " ";
}
d)
#include <iostream>
using namespace std;

void heapify(int arr[], int n, int i) {


int largest = i, l = 2*i + 1, r = 2*i + 2;
if (l < n && arr[l] > arr[largest]) largest = l;
124
125

if (r < n && arr[r] > arr[largest]) largest = r;


if (largest != i) {
swap(arr[i], arr[largest]);
heapify(arr, n, largest);
}
}
void heapSort(int arr[], int n) {
for (int i = n / 2 - 1; i >= 0; i--) heapify(arr, n, i);
for (int i = n - 1; i >= 0; i--) {
swap(arr[0], arr[i]);
heapify(arr, i, 0);
}
}
int main() {
int arr[] = {4, 10, 3, 5, 1};
int n = sizeof(arr)/sizeof(arr[0]);
heapSort(arr, n);
for (int i = 0; i < n; i++) cout << arr[i] << " ";
}

Result :
Hence,the above programs have been executed and verified successfully.
126

You might also like