Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 67

SUMMER INTERNSHIP REPORT

ON

“C++ AND DATA STRUCTURE”

Submitted in partial fulfilment the

Requirements for the Degree of

BACHELORS OF COMPUTER
APPLICATIONS

Uttaranchal School of Computing Sciences

MENTOR: SUBMITTED BY:

Mr. Parminder Singh Sagar Singh Rawat

Roll no. 52

BCA- 3rd Semester


ACKNOWLEDGEMENT

The most awaited moment of any endeavor is successful completion, but nothing can be
done successfully if done alone. Success is the outcome of the contribution and
consistent help of various persons and we thank those who helped us in the successful
completion of this project.
Primarily I would like to thank Dr. Sonal Sharma, Dean USCS for providing a healthy
and encouraging environment to study.
I profusely thankful to the department of computing Science, and Dr. Sameer Dev
Sharma, HOD, and my Project Mentor Mr. Parminder Singh. I am also thankful to
my mentor Mr. Akshay Rawat sir for guiding me throughout the internship period. He
has been generous enough to provide me an opportunity and accepting my candidature
for the most valuable guidance and affordable treatment given to us at every stage to
boost my morale.
.

Sagar Singh Rawat


BCA 3rd SEMESTER
DECLARATION

I hereby declare that the internship report entitled C++ AND DATA STRUCTURE is
submitted by Sagar Singh Rawat to Uttaranchal Institute of Management. The
internship was done under the guidance of Mr. Parminder Singh sir. I further declare
that the work reported in this internship has not been submitted and will not be
submitted, either in part or in full, for the award of any other degree or diploma in this
university or any other university or institute.

Sagar Singh Rawat


BCA-3rd semester

ii
CERTIFICATE OF ORIGINALITY

This is to certify that the internship entitled “C++ AND DATA STRUCTURE” by
Sagar Singh Rawat has been submitted in the partial fulfillment of the requirements for
the award of the degree of BCA from Uttaranchal University, Dehradun. The results
embodied in this project have not been submitted to any other University or Institution
for the record of any degree.

Under the guidance of:

Mr. Parminder Singh

Assistant Professor
Uttaranchal University
Dehradun

iii
COMPANY CERTIFICATE

iv
TABLE OF CONTENTS

CHAPTER TITLE PAGE


ACKNOWLEDGMENT i

DECALARATION ii
CERTIFICATE OF ORIGINALITY iii
COMPANY'S CERTIFICATE iv
TABLE OF CONTENTS v

1 INTRODUCTION 6
1.1 Objectives 6

2 COMPANY PROFILE 7
2.1 Services 7
2.2 Aim / Vision / Mission 7

3 BRIEF SUMMARY OF SIP 8


3.1 Overview of C++ 8
3.2 Why C++ 8
3.3 First week of internship 8-26
3.4 Second week of internship 26-37
3.5 Third week of internship 38-53
3.6 Fourth week of internship 53-65
3.7 Conclusion 66

v
Report Introduction: C++ and Data Structures

This report serves as an in-depth exploration of the pivotal roles played by C++
programming language and Data Structures within the domain of computer
science. C++ is a versatile language renowned for its amalgamation of
procedural and object-oriented programming paradigms. When coupled with a
profound understanding of Data Structures—specialized formats facilitating
efficient data organization—these concepts collectively form the cornerstone of
effective software development.

Report objective: C++ and Data Structures

This report aims to deeply explore the synergy between C++ and Data
Structures in computer science. It focuses on achieving a thorough
understanding of C++ fundamentals, emphasizing syntax and versatility.
Simultaneously, the report aims to instil proficiency in various data structures,
elucidating strengths and optimal applications.

The objective is to cultivate algorithmic thinking and problem-solving skills,


empowering readers to analyse algorithm complexities. Practical application is
paramount, guiding readers through hands-on implementation of C++ and Data
Structures in real-world scenarios. The report also delves into optimization
strategies, highlighting their impact on code efficiency. Emphasis on software
engineering best practices, including documentation and modular design, is
underscored. Ultimately, the report aims to demonstrate the practical application
of C++ and Data Structures in software development, providing readers with a
comprehensive understanding within a concise framework.

6
About - SLOG Solutions Pvt. Ltd.
SLOG Solutions Pvt. Ltd. Dehradun – Slog Solutions Private Limited, an ISO
9001:2015 certified, Uttarakhand's only MSME certified training company in
the engineering domain. Established in 2018, Slog offers various technologies
training to individuals all over India. We provide exceptional quality training of
each and every technology through our skilled trainers who are constantly
evolving to achieve their highest potential. Slog offers three types of services in
the engineering field
SLOG Dehradun – The reputed training institute in Dehradun has provided a
powerful training tool that can be used directly where training is required, Slog
has delivered thousands of skilled professionals to the industry. The Skill
Development Company offers an in-depth learning and industry compliance
training and certification to the individuals and corporate clients. Our company
providing great opportunities in the growing field to the students. We have best
career boosting options for the learners.

Mission Statement
SLOG Solutions Pvt. Ltd. Dehradun – The reputed training institute in
Dehradun has provided a powerful training tool that can be used directly where
training is required, Slog has delivered thousands of skilled professionals to the
industry.

Vision Statement
SLOG Solutions Pvt. Ltd. Dehradun – The reputed training institute in
Dehradun has provided a powerful training tool that can be used directly where
training is required, Slog has delivered thousands of skilled professionals to the
industry.

7
C++ And Data Structure

C++ Introduction

C++ is a cross-platform language that can be used to create high-performance


applications.
C++ was developed by Bjarne Stroustrup, as an extension to the C language.
C++ gives programmers a high level of control over system resources and
memory.

Why Use C++

C++ is one of the world's most popular programming languages.

C++ can be found in today's operating systems, Graphical User Interfaces, and
embedded systems.

C++ is an object-oriented programming language which gives a clear structure


to programs and allows code to be reused, lowering development costs.

C++ is portable and can be used to develop applications that can be adapted to
multiple platforms.

C++ is fun and easy to learn!

As C++ is close to C, C# and Java, it makes it easy for programmers to switch


to C++ or vice versa.

8
C++ Syntax
Let's break up the following code to understand it better:

Example

#include <iostream>
using namespace std;

int main() {
cout << "Hello World!";
return 0;
}

Omitting Namespace
You might see some C++ programs that runs without the standard namespace
library. The using namespace std line can be omitted and replaced with the std
keyword, followed by the :: operator for some objects:

Example

#include <iostream>

int main() {

std::cout << "Hello World!";

return 0;

9
C++ Variables
Variables are containers for storing data values.

In C++, there are different types of variables (defined with different keywords),
for example:

 int - stores integers (whole numbers), without decimals, such as 123 or -


123
 double - stores floating point numbers, with decimals, such as 19.99 or -
19.99
 char - stores single characters, such as 'a' or 'B'. Char values are
surrounded by single quotes
 string - stores text, such as "Hello World". String values are surrounded
by double quotes
 bool - stores values with two states: true or false

Declaring (Creating) Variables


To create a variable, specify the type and assign it a value:

Syntax

type variableName = value;

Where type is one of C++ types (such as int), and variableName is the name of
the variable (such as x or myName). The equal sign is used to assign values to
the variable.

To create a variable that should store a number, look at the following


example:
Create a variable called myNum of type int and assign it the value 15:

int myNum = 15;

cout << myNum;

10
You can also declare a variable without assigning the value, and assign the
value later:

int myNum;

myNum = 15;

cout << myNum;

Note that if you assign a new value to an existing variable, it will overwrite the
previous value:

int myNum = 15; // myNum is 15

myNum = 10; // Now myNum is 10

cout << myNum; // Outputs 10

Other Types
A demonstration of other data types:

Example

int myNum = 5; // Integer (whole number without decimals)

double myFloatNum = 5.99; // Floating point number (with decimals)

char myLetter = 'D'; // Character

string myText = "Hello"; // String (text)

bool myBoolean = true; // Boolean (true or false)

11
C++ Identifiers
All C++ variables must be identified with unique names.

These unique names are called identifiers.

Identifiers can be short names (like x and y) or more descriptive names (age,
sum, totalVolume).

Example

// Good

int minutesPerHour = 60;

// OK, but not so easy to understand what m actually is

int m = 60;

The general rules for naming variables are:

 Names can contain letters, digits and underscores


 Names must begin with a letter or an underscore (_)
 Names are case sensitive (myVar and myvar are different variables)
 Names cannot contain whitespaces or special characters like !, #, %, etc.
 Reserved words (like C++ keywords, such as int) cannot be used as
names.

Constants
When you do not want others (or yourself) to change existing variable values,
use the const keyword (this will declare the variable as "constant", which means
unchangeable and read-only):

Example

const int myNum = 15; // myNum will always be 15

myNum = 10; // error: assignment of read-only variable 'myNum'


12
C++ Data Types
As explained in the Variables chapter, a variable in C++ must be a specified
data type:

Example

int myNum = 5; // Integer (whole number)

float myFloatNum = 5.99; // Floating point number

double myDoubleNum = 9.98; // Floating point number

char myLetter = 'D'; // Character

bool myBoolean = true; // Boolean

string myText = "Hello"; // String

DATA TYPE SIZE DESCRIPTION

BOOLEAN 1 byte Stores true or false values

CHAR 1 byte Stores a single


character/letter/number, or ASCII
values

INT 2 or 4 bytes Stores whole numbers, without


decimals

FLOAT 4 bytes Stores fractional numbers, containing


one or more decimals. Sufficient for
storing 6-7 decimal digits

DOUBLE 8 bytes Stores fractional numbers, containing


one or more decimals. Sufficient for
storing 15 decimal digits

13
C++ Operators
Operators are used to perform operations on variables and values.

In the example below, we use the + operator to add together two values:

Example

int x = 100 + 50;


Although the + operator is often used to add together two values, like in the
example above, it can also be used to add together a variable and a value, or a
variable and another variable:

Example
int sum1 = 100 + 50; // 150 (100 + 50)
int sum2 = sum1 + 250; // 400 (150 + 250)
int sum3 = sum2 + sum2; // 800 (400 + 400)

C++ divides the operators into the following groups:

 Arithmetic operators
 Assignment operators
 Comparison operators
 Logical operators
 Bitwise operators

14
Arithmetic Operators

Arithmetic operators are used to perform common mathematical operations.

Operator Name Description Example


+ Addition Adds together two x+y
values
- Subtraction Subtracts one value x-y
from another

* Multiplication Multiplies two values x*y

/ Division Divides one value by x/y


another

% Modulus Returns the division x%y


remainder

++ Increment Increases the value of ++x


a variable by 1

-- Decrement Decreases the value of --x


a variable by 1

Assignment Operators

Assignment operators are used to assign values to variables.

In the example below, we use the assignment operator (=) to assign the value 10
to a variable called x:

Example
int x = 10;
The addition assignment operator (+=) adds a value to a variable:

Example
int x = 10;
x += 5;

A list of all assignment operators:


15
Operator Example Same As
= x=5 x=5
+= x += 3 x=x+3

-= x -= 3 x=x-3
*= x *= 3 x=x*3
/= x /= 3 x=x/3

%= x %= 3 x=x%3
&= x &= 3 x=x&3

|= x |= 3 x=x|3
^= x ^= 3 x=x^3
>>= x >>= 3 x = x >> 3

<<= x <<= 3 x = x << 3

Comparison Operators
Comparison operators are used to compare two values (or variables). This is
important in programming, because it helps us to find answers and make
decisions.

The return value of a comparison is either 1 or 0, which means true (1) or false
(0). These values are known as Boolean values, and you will learn more about
them in the Booleans and If..Else chapter.

In the following example, we use the greater than operator (>) to find out if 5 is
greater than 3:

Example
int x = 5;
int y = 3;
cout << (x > y); // returns 1 (true) because 5 is greater than 3

A list of all comparison operators:

16
Operator Name Example
== Equal to x == y
!= Not equal x != y
> Greater than x>y
< Less than x<y
>= Greater than or equal to x >= y

<= Less than or equal to x <= y

Logical Operators

As with comparison operators, you can also test for true (1) or false (0) values
with logical operators.

Logical operators are used to determine the logic between variables or values:

Operator Name Description Example


&& Logical and Returns true if x < 5 && x < 10
both statements are
true

|| Logical or Returns true if one x < 5 || x < 4


of the statements is
true

! Logical not Reverse the result, !(x < 5 && x < 10)
returns false if the
result is true

17
C++ Conditions and If Statements
You already know that C++ supports the usual logical conditions from
mathematics:

 Less than: a < b


 Less than or equal to: a <= b
 Greater than: a > b
 Greater than or equal to: a >= b
 Equal to a == b
 Not Equal to: a != b
You can use these conditions to perform different actions for different decisions.

C++ has the following conditional statements:

 Use if to specify a block of code to be executed, if a specified condition is


true
 Use else to specify a block of code to be executed, if the same condition
is false
 Use else if to specify a new condition to test, if the first condition is false
 Use switch to specify many alternative blocks of code to be executed
 The if Statement
 Use the if statement to specify a block of C++ code to be executed if a
condition is true.

Syntax
if (condition) {
// block of code to be executed if the condition is true
}

Example
if (20 > 18) {
cout << "20 is greater than 18";
}

Example
int x = 20;
int y = 18;
if (x > y) {
cout << "x is greater than y";
}
18
The else Statement
Use the else statement to specify a block of code to be executed if the condition
is false.

Syntax
if (condition) {
// block of code to be executed if the condition is true
} else {
// block of code to be executed if the condition is false
}

Example
int time = 20;
if (time < 18) {
cout << "Good day.";
} else {
cout << "Good evening.";
}
// Outputs "Good evening."

The else if Statement


Use the else if statement to specify a new condition if the first condition is false.

Syntax
if (condition1) {
// block of code to be executed if condition1 is true
} else if (condition2) {
// block of code to be executed if the condition1 is false and condition2 is true
} else {
// block of code to be executed if the condition1 is false and condition2 is false
}

Example
int time = 22;
if (time < 10) {
cout << "Good morning.";
} else if (time < 20) {
cout << "Good day.";
} else {
cout << "Good evening.";
}
// Outputs "Good evening."

19
C++ Loops
Loops can execute a block of code as long as a specified condition is reached.
Loops are handy because they save time, reduce errors, and they make code
more readable.

C++ While Loop

The while loop loops through a block of code as long as a specified condition is
true:

Syntax
while (condition) {
// code block to be executed
}
In the example below, the code in the loop will run, over and over again, as long
as a variable (i) is less than 5:

Example
int i = 0;
while (i < 5) {
cout << i << "\n";
i++;
}

The Do/While Loop

The do/while loop is a variant of the while loop. This loop will execute the code
block once, before checking if the condition is true, then it will repeat the loop
as long as the condition is true.

Syntax
do {
// code block to be executed
}
while (condition);

Example
int i = 0;

20
do {
cout << i << "\n";
i++;
}
while (i < 5);

C++ For Loop


When you know exactly how many times you want to loop through a block of
code, use the for loop instead of a while loop:

Syntax
for (statement 1; statement 2; statement 3) {
// code block to be executed
}
Statement 1 is executed (one time) before the execution of the code block.

Statement 2 defines the condition for executing the code block.

Statement 3 is executed (every time) after the code block has been executed.

The example below will print the numbers 0 to 4:

Example
for (int i = 0; i < 5; i++) {
cout << i << "\n";
}

Nested Loops
It is also possible to place a loop inside another loop. This is called a nested
loop.The "inner loop" will be executed one time for each iteration of the "outer
loop":

Example
// Outer loop
for (int i = 1; i <= 2; ++i) {
cout << "Outer: " << i << "\n"; // Executes 2 times

// Inner loop
for (int j = 1; j <= 3; ++j) {
cout << " Inner: " << j << "\n"; // Executes 6 times (2 * 3)
}
}

21
C++ Break and Continue

C++ Break
You have already seen the break statement used in an earlier chapter of this
tutorial. It was used to "jump out" of a switch statement.

The break statement can also be used to jump out of a loop.

This example jumps out of the loop when i is equal to 4:

Example
for (int i = 0; i < 10; i++) {
if (i == 4) {
break;
}
cout << i << "\n";
}

C++ Continue
The continue statement breaks one iteration (in the loop), if a specified
condition occurs, and continues with the next iteration in the loop.

This example skips the value of 4:

Example
for (int i = 0; i < 10; i++) {
if (i == 4) {
continue;
}
cout << i << "\n";
}

C++ Functions
A function is a block of code which only runs when it is called. You can pass
data, known as parameters, into a function. Functions are used to perform
certain actions, and they are important for reusing code: Define the code once,
and use it many times.

22
Create a Function

C++ provides some pre-defined functions, such as main(), which is used to


execute code. But you can also create your own functions to perform certain
actions.

To create (often referred to as declare) a function, specify the name of the


function, followed by parentheses ():

Syntax
void myFunction() {
// code to be executed
}

Call a Function

Declared functions are not executed immediately. They are "saved for later use",
and will be executed later, when they are called.

To call a function, write the function's name followed by two parentheses () and
a semicolon ;

In the following example, myFunction() is used to print a text (the action), when
it is called:

Example
Inside main, call myFunction():

// Create a function
void myFunction() {
cout << "I just got executed!";
}

int main() {
myFunction(); // call the function
return 0;
}

// Outputs "I just got executed!"

23
A function can be called multiple times:

Example
void myFunction() {
cout << "I just got executed!\n";
}

int main() {
myFunction();
myFunction();
myFunction();
return 0;
}
// I just got executed!
// I just got executed!
// I just got executed!

Function Declaration and Definition


A C++ function consist of two parts:

Declaration: the return type, the name of the function, and parameters (if any)

Definition: the body of the function (code to be executed)

void myFunction() { // declaration


// the body of the function (definition)
}

Example
int main() {
myFunction();
return 0;
}

void myFunction() {
cout << "I just got executed!";
}
// Error

24
Parameters and Arguments

Information can be passed to functions as a parameter. Parameters act as


variables inside the function.

Parameters are specified after the function name, inside the parentheses. You
can add as many parameters as you want, just separate them with a comma:

Syntax
void functionName(parameter1, parameter2, parameter3) {
// code to be executed
}

Example
void myFunction(string fname) {
cout << fname << " Refsnes\n";
}

int main() {
myFunction("Liam");
myFunction("Jenny");
myFunction("Anja");
return 0;
}

// Liam Refsnes
// Jenny Refsnes
// Anja Refsnes

Function Overloading

With function overloading, multiple functions can have the same name with
different parameters:

Example
int plusFuncInt(int x, int y) {
return x + y;
}
double plusFuncDouble(double x, double y) {

25
return x + y;
}

int main() {
int myNum1 = plusFuncInt(8, 5);
double myNum2 = plusFuncDouble(4.3, 6.26);
cout << "Int: " << myNum1 << "\n";
cout << "Double: " << myNum2;
return 0;
}

C++ Arrays

Arrays are used to store multiple values in a single variable, instead of declaring
separate variables for each value.

To declare an array, define the variable type, specify the name of the array
followed by square brackets and specify the number of elements it should store:

string cars[4];
We have now declared a variable that holds an array of four strings. To insert
values to it, we can use an array literal - place the values in a comma-separated
list, inside curly braces:

string cars[4] = {"Volvo", "BMW", "Ford", "Mazda"};


To create an array of three integers, you could write:

int myNum[3] = {10, 20, 30};


Access the Elements of an Array
You access an array element by referring to the index number inside square
brackets [].

This statement accesses the value of the first element in cars:

Example
string cars[4] = {"Volvo", "BMW", "Ford", "Mazda"};
cout << cars[0];
// Outputs Volvo

26
Change an Array Element
To change the value of a specific element, refer to the index number:

cars[0] = "Opel";

Example
string cars[4] = {"Volvo", "BMW", "Ford", "Mazda"};
cars[0] = "Opel";
cout << cars[0];
// Now outputs Opel instead of Volvo

C++ Arrays and Loops


Loop Through an Array
You can loop through the array elements with the for loop.

The following example outputs all elements in the cars array:

Example
string cars[5] = {"Volvo", "BMW", "Ford", "Mazda", "Tesla"};
for (int i = 0; i < 5; i++) {
cout << cars[i] << "\n";
}

Example
string cars[5] = {"Volvo", "BMW", "Ford", "Mazda", "Tesla"};
for (int i = 0; i < 5; i++) {
cout << i << " = " << cars[i] << "\n";
}
And this example shows how to loop through an array of integers:

Example
int myNumbers[5] = {10, 20, 30, 40, 50};
for (int i = 0; i < 5; i++) {
cout << myNumbers[i] << "\n";
}
The for-each Loop
There is also a "for-each loop", which is used exclusively to loop through
elements in an array:

Syntax
for (type variableName : arrayName) {
// code block to be executed
27
}

Example
int myNumbers[5] = {10, 20, 30, 40, 50};
for (int i : myNumbers) {
cout << i << "\n";
}

C++ Structures
Structures (also called structs) are a way to group several related variables into
one place. Each variable in the structure is known as a member of the structure.

Unlike an array, a structure can contain many different data types (int, string,
bool, etc.).

Create a Structure
To create a structure, use the struct keyword and declare each of its members
inside curly braces.

Example:
struct { // Structure declaration
int myNum; // Member (int variable)
string myString; // Member (string variable)
} myStructure; // Structure variable
Access Structure Members

Example
Assign data to members of a structure and print it:

// Create a structure variable called myStructure


struct {
int myNum;
string myString;
} myStructure;

// Assign values to members of myStructure


myStructure.myNum = 1;
myStructure.myString = "Hello World!";

// Print members of myStructure


cout << myStructure.myNum << "\n";
cout << myStructure.myString << "\n";

28
One Structure in Multiple Variables
You can use a comma (,) to use one structure in many variables:

struct {
int myNum;
string myString;
} myStruct1, myStruct2, myStruct3; // Multiple structure variables separated
with commas

Example
Use one structure to represent two cars:

struct {
string brand;
string model;
int year;
} myCar1, myCar2; // We can add variables by separating them with a comma
here

// Put data into the first structure


myCar1.brand = "BMW";
myCar1.model = "X5";
myCar1.year = 1999;

// Put data into the second structure


myCar2.brand = "Ford";
myCar2.model = "Mustang";
myCar2.year = 1969;

// Print the structure members


cout << myCar1.brand << " " << myCar1.model << " " << myCar1.year << "\
n";
cout << myCar2.brand << " " << myCar2.model << " " << myCar2.year << "\
n";

C++ Pointers
Creating Pointers
You learned from the previous chapter, that we can get the memory address of a
variable by using the & operator:

Example
string food = "Pizza"; // A food variable of type string

29
cout << food; // Outputs the value of food (Pizza)
cout << &food; // Outputs the memory address of food (0x6dfed4)
A pointer however, is a variable that stores the memory address as its value.

A pointer variable points to a data type (like int or string) of the same type, and
is created with the * operator. The address of the variable you're working with is
assigned to the pointer:

Example
string food = "Pizza"; // A food variable of type string
string* ptr = &food; // A pointer variable, with the name ptr, that stores the
address of food

// Output the value of food (Pizza)


cout << food << "\n";

// Output the memory address of food (0x6dfed4)


cout << &food << "\n";

// Output the memory address of food with the pointer (0x6dfed4)


cout << ptr << "\n";

C++ OOP
C++ What is OOP?
OOP stands for Object-Oriented Programming. Procedural programming is
about writing procedures or functions that perform operations on the data, while
object-oriented programming is about creating objects that contain both data
and functions.

Object-oriented programming has several advantages over procedural


programming:

 OOP is faster and easier to execute


 OOP provides a clear structure for the programs
 OOP helps to keep the C++ code DRY "Don't Repeat Yourself", and
makes the code easier to maintain, modify and debug

30
 OOP makes it possible to create full reusable applications with less code
and shorter development time.

C++ What are Classes and Objects?


Classes and objects are the two main aspects of object-oriented programming.
Look at the following illustration to see the difference between class and
objects:

Class Objects
Fruits Mango
Apple
Banana
So, a class is a template for objects, and an object is an instance of a class.
When the individual objects are created, they inherit all the variables and
functions from the class.
C++ Classes and Objects

C++ Classes/Objects

C++ is an object-oriented programming language.

Everything in C++ is associated with classes and objects, along with its
attributes and methods. For example: in real life, a car is an object. The car has
attributes, such as weight and color, and methods, such as drive and brake.

Attributes and methods are basically variables and functions that belongs to the
class. These are often referred to as "class members".

A class is a user-defined data type that we can use in our program, and it works
as an object constructor, or a "blueprint" for creating objects.

Create a Class
To create a class, use the class keyword:

Example
Create a class called "MyClass":

class MyClass { // The class


public: // Access specifier

31
int myNum; // Attribute (int variable)
string myString; // Attribute (string variable)
};

Create an Object
In C++, an object is created from a class. We have already created the class
named MyClass, so now we can use this to create objects. To create an object of
MyClass, specify the class name, followed by the object name.

To access the class attributes (myNum and myString), use the dot syntax (.) on
the object:

Example
Create an object called "myObj" and access the attributes:

class MyClass { // The class


public: // Access specifier
int myNum; // Attribute (int variable)
string myString; // Attribute (string variable)
};

int main() {
MyClass myObj; // Create an object of MyClass

// Access attributes and set values


myObj.myNum = 15;
myObj.myString = "Some text";

// Print attribute values


cout << myObj.myNum << "\n";
cout << myObj.myString;
return 0;
}

Class Methods

Methods are functions that belongs to the class.

There are two ways to define functions that belongs to a class:

Inside class definition

32
Outside class definition
In the following example, we define a function inside the class, and we name it
"myMethod".

Example
class MyClass { // The class
public: // Access specifier
void myMethod() { // Method/function defined inside the class
cout << "Hello World!";
}
};
int main() {
MyClass myObj; // Create an object of MyClass
myObj.myMethod(); // Call the method
return 0;
}
Parameters
You can also add parameters:

Example
#include <iostream>
using namespace std;

class Car {
public:
int speed(int maxSpeed);
};

int Car::speed(int maxSpeed) {


return maxSpeed;
}

int main() {
Car myObj; // Create an object of Car
cout << myObj.speed(200); // Call the method with an argument
return 0;
}

Access Specifiers

33
By now, you are quite familiar with the public keyword that appears in all of our
class examples:

Example
class MyClass { // The class
public: // Access specifier
// class members goes here
};
The public keyword is an access specifier. Access specifiers define how the
members (attributes and methods) of a class can be accessed. In the example
above, the members are public - which means that they can be accessed and
modified from outside the code.

In C++, there are three access specifiers:

Public - members are accessible from outside the class


Private - members cannot be accessed (or viewed) from outside the class
Protected - members cannot be accessed from outside the class, however, they
can be accessed in inherited classes. You will learn more about Inheritance later.
In the following example, we demonstrate the differences between public and
private members:

Example
class MyClass {
public: // Public access specifier
int x; // Public attribute
private: // Private access specifier
int y; // Private attribute
};

int main() {
MyClass myObj;
myObj.x = 25; // Allowed (public)
myObj.y = 50; // Not allowed (private)
return 0;
}
//If you try to access a private member, an error occurs:
error: y is private.

34
C++ Encapsulation
Encapsulation

The meaning of Encapsulation, is to make sure that "sensitive" data is hidden


from users. To achieve this, you must declare class variables/attributes as
private (cannot be accessed from outside the class). If you want others to read or
modify the value of a private member, you can provide public get and set
methods.

Access Private Members


To access a private attribute, use public "get" and "set" methods:

Example
#include <iostream>
using namespace std;

class Employee {
private:
// Private attribute
int salary;

public:
// Setter
void setSalary(int s) {
salary = s;
}
// Getter
int getSalary() {
return salary;
}
};

int main() {
Employee myObj;
myObj.setSalary(50000);
cout << myObj.getSalary();
return 0;
}

35
C++ Inheritance

Inheritance
In C++, it is possible to inherit attributes and methods from one class to another.
We group the "inheritance concept" into two categories:

derived class (child) - the class that inherits from another class
base class (parent) - the class being inherited from
To inherit from a class, use the : symbol.

In the example below, the Car class (child) inherits the attributes and methods
from the Vehicle class (parent):

Example
// Base class
class Vehicle {
public:
string brand = "Ford";
void honk() {
cout << "Tuut, tuut! \n" ;
}
};

// Derived class
class Car: public Vehicle {
public:
string model = "Mustang";
};

int main() {
Car myCar;
myCar.honk();
cout << myCar.brand + " " + myCar.model;
return 0;
}

C++ Polymorphism
36
Polymorphism

Polymorphism means "many forms", and it occurs when we have many classes
that are related to each other by inheritance.

Like we specified in the previous chapter; Inheritance lets us inherit attributes


and methods from another class. Polymorphism uses those methods to perform
different tasks. This allows us to perform a single action in different ways.

For example, think of a base class called Animal that has a method called
animalSound(). Derived classes of Animals could be Pigs, Cats, Dogs, Birds -
And they also have their own implementation of an animal sound (the pig oinks,
and the cat meows, etc.):

Example
// Base class
class Animal {
public:
void animalSound() {
cout << "The animal makes a sound \n";
}
};

// Derived class
class Pig : public Animal {
public:
void animalSound() {
cout << "The pig says: wee wee \n";
}
};

// Derived class
class Dog : public Animal {
public:
void animalSound() {
cout << "The dog says: bow wow \n";
}
};

37
C++ DSA

Introduction to C++ DSA


C++ is one of the common programming languages that is mainly used in the
development of high-performance applications, Operating Systems, and games.
C++ is a powerful and efficient language that provides a wide range of Data
Structures and Algorithms for complex data processing tasks. C++ Data
Structures and Algorithms (DSA) is a part of Computer Science in which there
is the study of different Algorithms and Data Structures using the C++
programming language.

In this article, we will explore the fundamentals of C++ DSA, including Data
Structures and Algorithms, their importance, and how they can be used to solve
real-world problems.

What is the Meaning of Data Structures and Algorithms?


Data Structures are the basic block of Computer Science Technology. Data
Structures are used to store the data in such a way that we can access them in a
very efficient way. There are a lot of Data Structures used in the C++
Programming language Arrays, Stacks, Queues, Linked-lists, Trees, and Graphs.

To solve a specific problem, we require an optimal solution or approach, and in


programming, it is also called Algorithm. They are used to manipulate the data
stored in the Data Structures to perform operations such as Searching, Sorting,
and Traversal.

Why are Data Structures and Algorithms Important?


Data Structures and Algorithms are an essential part of Computer Science and
programming. They are used to solve real-world problems by processing and
manipulating large amounts of data. If we use the Data Structures and
Algorithms efficiently, then we can increase the execution speed of the program
and reduce the time.

For example, consider a program that needs to search for a particular item in a
large dataset. Using an efficient search Algorithm like Binary Search can
significantly reduce the search time and improve the performance of the
program. Similarly, using an appropriate Data Structure like a Hash Table can

38
significantly reduce the time required to Insert, Search, and Delete items from a
dataset.

Binary search
The binary search algorithm is a divide and conquer algorithm that you can use
to search for and find elements in a sorted array.

The algorithm is fast in searching for elements because it removes half of the
array every time the search iteration happens.

So instead of searching through the whole array, the algorithm removes half of
the array where the element to be searched for can't be found. It does this
continuously until the element is found.

In a case where the element to be searched for doesn't exist, it returns a value of
-1. If the element exists, then it returns the index of the element.

If the explanations above seem complex, then you should check out this visual
guide on how the binary search algorithm works.

In this article, you'll see an implementation of the binary search algorithm in C+


+.

Binary Search Algorithm Example in C++

#include <iostream>
using namespace std;

int binarySearch(int array[], int low, int high, int number_to_search_for) {

while (low <= high) {


int mid = low + (high - low) / 2;

if (number_to_search_for == array[mid]){
return mid;
}

if (number_to_search_for > array[mid]){


low = mid + 1;
}

if (number_to_search_for < array[mid]){


high = mid - 1;
39
}

return -1;
}

int main(void) {
int arrayOfNums[] = {2,4,7,9,10,13,20};

int n = sizeof(arrayOfNums) / sizeof(arrayOfNums[0]);

int result = binarySearch(arrayOfNums, 0, n - 1, 13);

if (result == -1){
printf("Element doesn't exist in the array");
}
else{
printf("The index of the element is %d", result);
}

// The index of the element is 5


}

Steps to perform the binary search in C++

Step 1: Declare the variables and input all elements of an array in sorted order
(ascending or descending).

Step 2: Divide the lists of array elements into halves.

Step 3: Now compare the target elements with the middle element of the array.
And if the value of the target element is matched with the middle element,
return the middle element's position and end the search process.

Step 4: If the target element is less than the middle element, we search the
elements into the lower half of an array.

Step 5: If the target element is larger than the middle element, we need to search
the element into the greater half of the array.

Step 6: We will continuously repeat steps 4, 5, and 6 till the specified element is
not found in the sorted array.

40
Merge Sort

Merge Sort is one of the most popular sorting algorithms that is based on the
principle of Divide and Conquer Algorithm.

Here, a problem is divided into multiple sub-problems. Each sub-problem is


solved individually. Finally, sub-problems are combined to form the final
solution.

Merge Sort example


Divide and Conquer Strategy
Using the Divide and Conquer technique, we divide a problem into
subproblems. When the solution to each subproblem is ready, we 'combine' the
results from the subproblems to solve the main problem.

Suppose we had to sort an array A. A subproblem would be to sort a sub-section


of this array starting at index p and ending at index r, denoted as A[p..r].

Divide

If q is the half-way point between p and r, then we can split the subarray A[p..r]
into two arrays A[p..q] and A[q+1, r].

Conquer

In the conquer step, we try to sort both the subarrays A[p..q] and A[q+1, r]. If
we haven't yet reached the base case, we again divide both these subarrays and
try to sort them.

Combine

When the conquer step reaches the base step and we get two sorted subarrays
A[p..q] and A[q+1, r] for array A[p..r], we combine the results by creating a
sorted array A[p..r] from two sorted subarrays A[p..q] and A[q+1, r].

Merge sort is performed using the following steps:

41
#1) The list to be sorted is divided into two arrays of equal length by dividing
the list on the middle element. If the number of elements in the list is either 0 or
1, then the list is considered sorted.

#2) Each sublist is sorted individually by using merge sort recursively.

#3) The sorted sublists are then combined or merged together to form a
complete sorted list.

General Algorithm
The general pseudo-code for the merge sort technique is given below.

Declare an array Arr of length N


If N=1, Arr is already sorted
If N>1,
Left = 0, right = N-1
Find middle = (left + right)/2
Call merge_sort(Arr,left,middle) =>sort first half recursively
Call merge_sort(Arr,middle+1,right) => sort second half recursively
Call merge(Arr, left, middle, right) to merge sorted arrays in above steps.
Exit

Pseudo code for merge sort

#include <iostream>

using namespace std;

// A function to merge the two half into a sorted data.


void Merge(int *a, int low, int high, int mid)
{
// We have low to mid and mid+1 to high already sorted.
int i, j, k, temp[high-low+1];
i = low;
k = 0;
j = mid + 1;

// Merge the two parts into temp[].


while (i <= mid && j <= high)
{
if (a[i] < a[j])
{
temp[k] = a[i];

42
k++;
i++;
}
else
{
temp[k] = a[j];
k++;
j++;
}
}

// Insert all the remaining values from i to mid into temp[].


while (i <= mid)
{
temp[k] = a[i];
k++;
i++;
}

// Insert all the remaining values from j to high into temp[].


while (j <= high)
{
temp[k] = a[j];
k++;
j++;
}

// Assign sorted data stored in temp[] to a[].


for (i = low; i <= high; i++)
{
a[i] = temp[i-low];
}
}

// A function to split array into two parts.


void MergeSort(int *a, int low, int high)
{
int mid;
if (low < high)
{
mid=(low+high)/2;
// Split the data into two half.
MergeSort(a, low, mid);
MergeSort(a, mid+1, high);
43
// Merge them to get sorted output.
Merge(a, low, high, mid);
}
}

int main()
{
int n, i;
cout<<"\nEnter the number of data element to be sorted: ";
cin>>n;

int arr[n];
for(i = 0; i < n; i++)
{
cout<<"Enter element "<<i+1<<": ";
cin>>arr[i];
}

MergeSort(arr, 0, n-1);

// Printing the sorted data.


cout<<"\nSorted Data ";
for (i = 0; i < n; i++)
cout<<"->"<<arr[i];

return 0;
}

Linked List in C++


A linked list is a kind of linear dynamic data structure which we use to store
data elements. Arrays are also a type of linear data structure where the data
items are stored in continuous memory blocks.

Unlike arrays, the linked list does not need to store data elements in contiguous
memory regions or blocks.

A linked list is composed of elements known as "Nodes" that are divided into
two parts. The first component is the part where we store the actual data, and the
second is a part where we store the pointer to the next node. This type of
structure is known as a "singly linked list."

44
1) Insertion

The linked list is expanded by the action of adding to it. Although it would seem
simple, given the linked list's structure, we know that every time a data item is
added, we must change the next pointers of the previous and next nodes of the
new item that we have added.

Where the new data item will be inserted is the second aspect to think about.

There are three places where a data item can be added to the linked list.

a. Beginning with the linked list

Below is a connected list of the numbers 2->4->6->8->10. The head pointing to


node 2 will now point to node 1, and the next pointer of node 1 will have the
memory address of node 2, as shown in the illustration below, if we add a new
node 1 as the first node in the list.

Linked List Data Structure in C++ With Illustration


As a result, the new linked list is 1->2->4->6->8->10.

b. After the given Node

In this case, we are given a node and must add a new node behind it. The linked
list will seem as follows if node f is added to the linked list a->b->c->d->e after
node c:

Linked List Data Structure in C++ With Illustration


We therefore check to see if the specified node is present in the diagram above.
If it is present, a new node f is created. After that, we point node c's next pointer
at the brand-new node f. The node f's next pointer now points to node d.

c. The Linked List's last item

In the third case, a new node is added to the end of the linked list. Take into
account the linked list below: a->b->c->d->e, with the addition of node f at the
end. After adding the node, the linked list will appear like this.

Linked List Data Structure in C++ With Illustration


As a result, we construct a new node f. The tail pointer leading to null is then
pointed to f, and node f's next pointer is pointed to null. In the Programming
language below, we have generated all three types of insert functions.

45
A linked list can be declared as a structure or as a class in C++. A linked list
declared as a structure is a classic C-style statement. A linked list is used as a
class in modern C++, mainly when using the standard template library.

Structure was used in the following application to declare and generate a linked
list. Its members will be data and a pointer to the following element.

C++ Program:

#include <iostream>
using namespace std;

struct Node
{
int data;
struct Node *next;
};
void push ( struct Node** head, int nodeData )
{
struct Node* newNode1 = new Node;

newNode1 -> data = nodeData;


newNode1 -> next = (*head);

(*head) = newNode1;
}
void insertAfter ( struct Node* prevNode, int nodeData )
{
if ( prevNode == NULL )
{
cout << "the given previous node is required,cannot be NULL";
return;

}
struct Node* newNode1 =new Node;
newNode1 -> data = nodeData;
newNode1 -> next = prevNode -> next;
prevNode -> next = newNode1;
}
void append ( struct Node** head, int nodeData )
{
struct Node* newNode1 = new Node;

46
struct Node *last = *head;
newNode1 -> data = nodeData;
newNode1 -> next = NULL;
if ( *head == NULL )
{
*head = newNode1;
return;
}
while ( last -> next != NULL )
last = last -> next;
last -> next = newNode1;
return;
}
void displayList ( struct Node *node )
{
while ( node != NULL )
{
cout << node -> data << "-->";
node = node -> next;
}

if ( node== NULL)
cout<<"null";
}
int main ()
{
struct Node* head = NULL;
append ( &head, 15 );
push ( &head, 25 );
push ( &head, 35 );
append ( &head, 45 );
insertAfter ( head -> next, 55 );

cout << "Final linked list: " << endl;


displayList (head);

return 0;
}
Output:

Final linked list:


35-->25-->55-->15-->45-->null

47
2) Deletion

Similar to insertion, deleting a node from a linked list requires many points
from which the node might be eliminated. We can remove the linked list's first,
last, or kth node at random. We must correctly update the next pointer and all
other linked list pointers in order to maintain the linked list after deletion.

In the following C++ implementation, we have two deletion methods: deleting


the list's initial node and deleting the list's last node. We begin by adding nodes
to the head of the list. The list's contents are then shown following each addition
and deletion.

C++ Program:

#include <iostream>
using namespace std;
struct Node {
int data;
struct Node* next;
};
Node* deletingFirstNode ( struct Node* head )
{
if ( head == NULL )
return NULL;
Node* tempNode = head;
head = head -> next;
delete tempNode;

return head;
}
Node* removingLastNode ( struct Node* head )
{
if ( head == NULL )
return NULL;

if ( head -> next == NULL ) {


delete head;
return NULL;
}
Node* secondLast = head;
while ( secondLast -> next -> next != NULL )
secondLast = secondLast->next;
delete ( secondLast -> next );

48
secondLast -> next = NULL;

return head;
}
void push ( struct Node** head, int newData )
{
struct Node* newNode1 = new Node;
newNode1 -> data = newData;
newNode1 -> next = ( *head );
( *head ) = newNode1;
}
int main()
{
Node* head = NULL;
push ( &head, 25 );
push ( &head, 45 );
push ( &head, 65);
push ( &head, 85 );
push ( &head, 95 );

Node* temp;

cout << "Linked list created " << endl; for ( temp = head; temp != NULL;
temp = temp -> next )
cout << temp->data << "-->";
if ( temp == NULL )
cout << "NULL" << endl;
head = deletingFirstNode (head);
cout << "Linked list after deleting head node" << endl; for ( temp = head;
temp != NULL; temp = temp -> next )
cout << temp->data << "-->";
if ( temp == NULL )
cout<<"NULL"<<endl;
head = removingLastNode (head);
cout << "Linked list after deleting last node" << endl; for ( temp = head;
temp != NULL; temp = temp -> next )
cout << temp -> data << "-->";
if ( temp == NULL )
cout << "NULL";

return 0;
}

Output:
49
Linked list created
95-->85-->65-->45-->25-->NULL
Linked list after deleting head node
85-->65-->45-->25-->NULL
Linked list after deleting last node
85-->65-->45-->NULL

Linked List Traversal

Traversing through a linked list is very easy. It requires creating a temp node
pointing to the head of the list. If the temp node is not null, display its content
and move to the next node using temp next. Repeat the process till the temp
node becomes null. If the temp node is empty at the start, then the list contains
no item.

void PrintList() {

//1. create a temp node pointing to head


Node* temp = head;

//2. if the temp node is not null continue


// displaying the content and move to the
// next node till the temp becomes null
if(temp != NULL) {
cout<<"The list contains: ";
while(temp != NULL) {
cout<<temp->data<<" ";
temp = temp->next;
}
cout<<endl;
} else {

//3. If the temp node is null at the start,


// the list is empty
cout<<"The list is empty.\n";
}
}

50
Circular Linked List In C++

The arrangement shown below is for a singly linked list.

singly linked list

A circular linked list can be a singly linked list or a doubly linked list. In a
doubly circular linked list, the previous pointer of the first node is connected to
the last node while the next pointer of the last node is connected to the first
node.

Its representation is shown below.

doubly circular linked list

Declaration
We can declare a node in a circular linked list as any other node as shown
below:

struct Node
{
int data;
struct Node *next;
};
In order to implement the circular linked list, we maintain an external pointer
“last” that points to the last node in the circular linked list. Hence last->next will
point to the first node in the linked list.

By doing this we ensure that when we insert a new node at the beginning or at
the end of the list, we need not traverse the entire list. This is because the last
points to the last node while last->next points to the first node.

This wouldn’t have been possible if we had pointed the external pointer to the
first node.

Basic Operations

The circular linked list supports insertion, deletion, and traversal of the list. We
will discuss each of the operations in detail now.

Insertion

51
We can insert a node in a circular linked list either as a first node (empty list), in
the beginning, in the end, or in between the other nodes. Let us see each of these
insertion operations using a pictorial representation below.

1) Insert in an empty list

Insert in an empty list

When there are no nodes in circular list and the list is empty, the last pointer is
null, then we insert a new node N by pointing the last pointer to the node N as
shown above. The next pointer of N will point to the node N itself as there is
only one node. Thus N becomes the first as well as last node in the list.

2) Insert at the beginning of the list #

Insert at the beginning of the list

As shown in the above representation, when we add a node at the beginning of


the list, the next pointer of the last node points to the new node N thereby
making it a first node.

N->next = last->next

Last->next = N

3) Insert at the end of the list

last node points to the new node

To insert a new node at the end of the list, we follow these steps:

N-> next = last ->next;


last ->next = N
last = N

4) Insert in between the list

Insert in between the list

Suppose we need to insert a new node N between N3 and N4, we first need to
traverse the list and locate the node after which the new node is to be inserted,
in this case, its N3.

52
Deletion
The deletion operation of the circular linked list involves locating the node that
is to be deleted and then freeing its memory.

For this we maintain two additional pointers curr and prev and then traverse the
list to locate the node. The given node to be deleted can be the first node, the
last node or the node in between. Depending on the location we set the curr and
prev pointers and then delete the curr node.

Traversal
Traversal is a technique of visiting each and every node. In linear linked lists
like singly linked list and doubly linked lists, traversal is easy as we visit each
node and stop when NULL is encountered.

However, this is not possible in a circular linked list. In a circular linked list, we
start from the next of the last node which is the first node and traverse each
node. We stop when we once again reach the first node.

Now we present an implementation of the circular linked list operations using


C++ and Java. We have implemented insertion, deletion and traversal operations
here. For a clear understanding, we have depicted the circular linked list as

C++ queue
In computer science we go for working on a large variety of programs. Each of
them has their own domain and utility. Based on the purpose and environment
of the program creation, we have a large number of data structures available to
choose from. One of them is 'queues. Before discussing about this data type let
us take a look at its syntax.

Syntax
template<class T, class Container = deque<T> > class queue;
This data structure works on the FIFO technique, where FIFO stands for First In
First Out. The element which was first inserted will be extracted at the first and
so on. There is an element called as 'front' which is the element at the front most
position or say the first position, also there is an element called as 'rear' which is

53
the element at the last position. In normal queues insertion of elements take at
the rear end and the deletion is done from the front.

Queues in the application areas are implied as the container adaptors.

Functions
With the help of functions, an object or variable can be played with in the field
of programming. Queues provide a large number of functions that can be used
or embedded in the programs. A list of the same is given below:

Function Description
(constructor) The function is used for the construction of a
queue container.
empty The function is used to test for the emptiness of
a queue. If the queue is empty the function
returns true else false.
size The function returns the size of the queue
container, which is a measure of the number of
elements stored in the queue.
front The function is used to access the front element
of the queue. The element plays a very
important role as all the deletion operations are
performed at the front element.
back The function is used to access the rear element
of the queue. The element plays a very
important role as all the insertion operations are
performed at the rear element.
push The function is used for the insertion of a new
element at the rear end of the queue.
pop The function is used for the deletion of element;
the element in the queue is deleted from the
front end.
emplace The function is used for insertion of new
elements in the queue above the current rear
element.
swap The function is used for interchanging the
contents of two containers in reference.
relational operators The non member function specifies the
relational operators that are needed for the
queues.
uses allocator<queue> As the name suggests the non member function
uses the allocator for the queues.

54
Example: A simple program to show the use of basic queue functions.
#include <iostream>
#include <queue>
using namespace std;
void showsg(queue <int> sg)
{
queue <int> ss = sg;
while (!ss.empty())
{
cout << '\t' << ss.front();
ss.pop();
}
cout << '\n';
}

int main()
{
queue <int> fquiz;
fquiz.push(10);
fquiz.push(20);
fquiz.push(30);

cout << "The queue fquiz is : ";


showsg(fquiz);

cout << "\nfquiz.size() : " << fquiz.size();


cout << "\nfquiz.front() : " << fquiz.front();
cout << "\nfquiz.back() : " << fquiz.back();

cout << "\nfquiz.pop() : ";


fquiz.pop();
showsg(fquiz);

return 0;
}

Types of Queue
There are four different types of queue that are listed as follows -

 Simple Queue or Linear Queue


 Circular Queue
 Priority Queue

55
 Double Ended Queue (or Deque)

Let's discuss each of the type of queue.

Simple Queue or Linear Queue


In Linear Queue, an insertion takes place from one end while the deletion
occurs from another end. The end at which the insertion takes place is known as
the rear end, and the end at which the deletion takes place is known as front end.
It strictly follows the FIFO rule.

The major drawback of using a linear Queue is that insertion is done only from
the rear end. If the first three elements are deleted from the Queue, we cannot
insert more elements even though the space is available in a Linear Queue. In
this case, the linear Queue shows the overflow condition as the rear is pointing
to the last element of the Queue.

Circular Queue
In Circular Queue, all the nodes are represented as circular. It is similar to the
linear Queue except that the last element of the queue is connected to the first
element. It is also known as Ring Buffer, as all the ends are connected to
another end. The representation of circular queue is shown in the below image -

The drawback that occurs in a linear queue is overcome by using the circular
queue. If the empty space is available in a circular queue, the new element can
be added in an empty space by simply incrementing the value of rear. The main
advantage of using the circular queue is better memory utilization.

Priority Queue
It is a special type of queue in which the elements are arranged based on the
priority. It is a special type of queue data structure in which every element has a
priority associated with it. Suppose some elements occur with the same priority,
they will be arranged according to the FIFO principle. The representation of
priority queue is shown in the below image -

Insertion in priority queue takes place based on the arrival, while deletion in the
priority queue occurs based on the priority. Priority queue is mainly used to
implement the CPU scheduling algorithms.

There are two types of priority queue that are discussed as follows

56
Ascending priority queue - In ascending priority queue, elements can be
inserted in arbitrary order, but only smallest can be deleted first. Suppose an
array with elements 7, 5, and 3 in the same order, so, insertion can be done with
the same sequence, but the order of deleting the elements is 3, 5, 7.
Descending priority queue - In descending priority queue, elements can be
inserted in arbitrary order, but only the largest element can be deleted first.
Suppose an array with elements 7, 3, and 5 in the same order, so, insertion can
be done with the same sequence, but the order of deleting the elements is 7, 5, 3.

Deque (or, Double Ended Queue)


In Deque or Double Ended Queue, insertion and deletion can be done from both
ends of the queue either from the front or rear. It means that we can insert and
delete elements from both front and rear ends of the queue. Deque can be used
as a palindrome checker means that if we read the string from both ends, then
the string would be the same.

Deque can be used both as stack and queue as it allows the insertion and
deletion operations on both ends. Deque can be considered as stack because
stack follows the LIFO (Last In First Out) principle in which insertion and
deletion both can be performed only from one end. And in deque, it is possible
to perform both insertion and deletion from one end, and Deque does not follow
the FIFO principle.

Operations performed on queue

 Enqueue: The Enqueue operation is used to insert the element at the rear
end of the queue. It returns void.
 Dequeue: It performs the deletion from the front-end of the queue. It also
returns the element which has been removed from the front-end. It returns
an integer value.
 Peek: This is the third operation that returns the element, which is pointed
by the front pointer in the queue but does not delete it.
 Queue overflow (isfull): It shows the overflow condition when the queue
is completely full.
 Queue underflow (isempty): It shows the underflow condition when the
Queue is empty, i.e., no elements are in the Queue.

Tree Data Structure

57
We read the linear data structures like an array, linked list, stack and queue in
which all the elements are arranged in a sequential manner. The different data
structures are used for different kinds of data.

A tree is also one of the data structures that represent hierarchical data.

Let’s understand some key points of the Tree data structure.

A tree data structure is defined as a collection of objects or entities known as


nodes that are linked together to represent or simulate hierarchy.
A tree data structure is a non-linear data structure because it does not store in a
sequential manner. It is a hierarchical structure as elements in a Tree are
arranged in multiple levels.
In the Tree data structure, the topmost node is known as a root node. Each node
contains some data, and data can be of any type. In the above tree structure, the
node contains the name of the employee, so the type of data would be a string.
Each node contains some data and the link or reference of other nodes that can
be called children.
Some basic terms used in Tree data structure.
Let’s consider the tree structure, which is shown below:

In the above structure, each node is labeled with some number. Each arrow
shown in the above figure is known as a link between the two nodes.

 Root: The root node is the topmost node in the tree hierarchy. In other
words, the root node is the one that doesn’t have any parent. In the above
structure, node numbered 1 is the root node of the tree. If a node is
directly linked to some other node, it would be called a parent-child
relationship.
 Child node: If the node is a descendant of any node, then the node is
known as a child node.
 Parent: If the node contains any sub-node, then that node is said to be the
parent of that sub-node.
 Sibling: The nodes that have the same parent are known as siblings.
 Leaf Node:- The node of the tree, which doesn’t have any child node, is
called a leaf node. A leaf node is the bottom-most node of the tree. There
can be any number of leaf nodes present in a general tree. Leaf nodes can
also be called external nodes.
 Internal nodes: A node has at least one child node known as an internal

58
 Ancestor node:- An ancestor of a node is any predecessor node on a path
from the root to that node. The root node doesn’t have any ancestors. In
the tree shown in the above image, nodes 1, 2, and 5 are the ancestors of
node 10.
 Descendant: The immediate successor of the given node is known as a
descendant of a node. In the above figure, 10 is the descendant of node 5.

Implementation:

// Binary Tree in C++


#include <stdlib.h>
#include <iostream>
using namespace std;
struct node {
int data;
struct node *left;
struct node *right;
};
// New node creation
struct node *newNode(int data) {
struct node *node = (struct node *)malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return (node);
}
// Traverse Preorder
void traversePreOrder(struct node *temp) {
if (temp != NULL) {
cout << " " << temp->data;
traversePreOrder(temp->left);
traversePreOrder(temp->right);
}
}
// Traverse Inorder
void traverseInOrder(struct node *temp) {
if (temp != NULL) {
traverseInOrder(temp->left);
cout << " " << temp->data;
traverseInOrder(temp->right);
}

59
}
// Traverse Postorder
void traversePostOrder(struct node *temp) {
if (temp != NULL) {
traversePostOrder(temp->left);
traversePostOrder(temp->right);
cout << " " << temp->data;
}
}
int main() {
struct node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
cout << "preorder traversal: ";
traversePreOrder(root);
cout << "\nInorder traversal: ";
traverseInOrder(root);
cout << "\nPostorder traversal: ";
traversePostOrder(root);

Binary Search Tree(BST):


A binary search tree follows some order to arrange the elements. In a Binary
search tree, the value of the left node must be smaller than the parent node, and
the value of the right node must be greater than the parent node. This rule is
applied recursively to the left and right subtrees of the root.

Implementation

// Binary Search Tree operations in C++


#include <iostream>
using namespace std;
struct node {
int key;
struct node *left, *right;
};
// Create a node
struct node *newNode(int item) {
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->key = item;
temp->left = temp->right = NULL;

60
return temp;
}
// Inorder Traversal
void inorder(struct node *root) {
if (root != NULL) {
// Traverse left
inorder(root->left);
// Traverse root
cout << root->key << " -> ";
// Traverse right
inorder(root->right);
}
}
// Insert a node
struct node *insert(struct node *node, int key) {
// Return a new node if the tree is empty
if (node == NULL) return newNode(key);
// Traverse to the right place and insert the node
if (key < node->key)
node->left = insert(node->left, key);
else
node->right = insert(node->right, key);
return node;
}
// Find the inorder successor
struct node *minValueNode(struct node *node) {
struct node *current = node;
// Find the leftmost leaf
while (current && current->left != NULL)
current = current->left;
return current;
}
// Deleting a node
struct node *deleteNode(struct node *root, int key) {
// Return if the tree is empty
if (root == NULL) return root;
// Find the node to be deleted
if (key < root->key)
root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
else {
// If the node is with only one child or no child

61
if (root->left == NULL) {
struct node *temp = root->right;
free(root);
return temp;
} else if (root->right == NULL) {
struct node *temp = root->left;
free(root);
return temp;
}
// If the node has two children
struct node *temp = minValueNode(root->right);
// Place the inorder successor in position of the node to be deleted
root->key = temp->key;
// Delete the inorder successor
root->right = deleteNode(root->right, temp->key);
}
return root;
}
// Driver code
int main() {
struct node *root = NULL;
root = insert(root, 8);
root = insert(root, 3);
root = insert(root, 1);
root = insert(root, 6);
root = insert(root, 7);
root = insert(root, 10);
root = insert(root, 14);
root = insert(root, 4);
cout << "Inorder traversal: ";
inorder(root);
cout << "\nAfter deleting 10\n";
root = deleteNode(root, 10);
cout << "Inorder traversal: ";
inorder(root);
}

Graph:
A graph can be defined as a group of vertices and edges that are used to connect
these vertices. A graph can be seen as a cyclic tree, where the vertices (Nodes)

62
maintain any complex relationship among them instead of having parent-child
relationship.

Directed and Undirected Graph


A graph can be directed or undirected. However, in an undirected graph, edges
are not associated with the directions with them. An undirected graph is shown
in the above figure since its edges are not attached with any of the directions. If
an edge exists between vertex A and B then the vertices can be traversed from B
to A as well as A to B.

In a directed graph, edges form an ordered pair. Edges represent a specific path
from some vertex A to another vertex B. Node A is called the initial node while
node B is called terminal node.
A directed graph is shown in the following figure.

Graph is represented by two methods:

Adjacency Matrix

An adjacency matrix is a 2D array of V x V vertices. Each row and column


represent a vertex.
If the value of any element a [i][j] is 1, it represents that there is an edge
connecting vertex i and vertex j.

Implementation:

#include<iostream>
using namespace std;
int vertArr[20][20]; //the adjacency matrix initially 0
int count = 0;
void displayMatrix(int v) {
int i, j;
for(i = 0; i < v; i++) {
for(j = 0; j < v; j++) {
cout << vertArr[i][j] << " ";
}
cout << endl;
}
}

63
void add_edge(int u, int v) { //function to add edge into the matrix
vertArr[u][v] = 1;
vertArr[v][u] = 1;
}
main(int argc, char* argv[]) {
int v = 6; //there are 6 vertices in the graph
add_edge(0, 4);
add_edge(0, 3);
add_edge(1, 2);
add_edge(1, 4);
add_edge(1, 5);
add_edge(2, 3);
add_edge(2, 5);
add_edge(5, 3);
add_edge(5, 4);
displayMatrix(v);
}

Adjacency List

An adjacency list represents a graph as an array of linked lists.


The index of the array represents a vertex and each element in its linked list
represents the other vertices that form an edge with the vertex.

Implementation:

// A simple representation of graph using STL


#include <bits/stdc++.h>
using namespace std;
// A utility function to add an edge in an
// undirected graph.
void addEdge(vector<int> adj[], int u, int v)
{
adj[u].push_back(v);
adj[v].push_back(u);
}
// A utility function to print the adjacency list
// representation of graph
void printGraph(vector<int> adj[], int V)
{
for (int v = 0; v < V; ++v) {
cout << "\n Adjacency list of vertex " << v
<< "\n head ";

64
for (auto x : adj[v])
cout << "-> " << x;
printf("\n");
}
}
// Driver code
int main()
{
int V = 5;
vector<int> adj[V];
addEdge(adj, 0, 1);
addEdge(adj, 0, 4);
addEdge(adj, 1, 2);
addEdge(adj, 1, 3);
addEdge(adj, 1, 4);
addEdge(adj, 2, 3);
addEdge(adj, 3, 4);
printGraph(adj, V);
return 0;
}

65
Conclusion
In conclusion, the symbiotic relationship between C++ and Data Structures
emerges as a cornerstone in the field of computer science. The thorough
exploration of C++ fundamentals and diverse data structures provides a robust
foundation for both theoretical understanding and practical application. The
emphasis on algorithmic thinking and problem-solving equips individuals with
essential skills for efficient solution development.

The practical implementation of C++ and Data Structures in real-world


scenarios reinforces the significance of these concepts in software development.
Optimization techniques and adherence to software engineering best practices
further underscore their crucial roles in crafting efficient, maintainable, and
scalable code.

As we conclude, it is evident that a mastery of C++ and Data Structures is not


merely an academic pursuit but a practical necessity for navigating the
complexities of modern computing. This report serves as a guide, illuminating
the significance and applications of these fundamental elements, empowering
individuals to excel in diverse realms within the dynamic landscape of computer
science.

66

You might also like