0% found this document useful (0 votes)
16 views

Unite 2 and 3 and 4

1) Functions allow programmers to organize code into reusable blocks to perform specific tasks. There are two types of functions: standard library functions and user-defined functions. 2) User-defined functions in C++ are defined by the programmer. They are declared with a name, return type, and parameters. Functions can optionally return values using the return statement. 3) Functions improve code readability and maintainability by separating a program into smaller, well-defined units. Parameters allow functions to accept input values, while return values allow functions to return results.

Uploaded by

Prakhar Billore
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)
16 views

Unite 2 and 3 and 4

1) Functions allow programmers to organize code into reusable blocks to perform specific tasks. There are two types of functions: standard library functions and user-defined functions. 2) User-defined functions in C++ are defined by the programmer. They are declared with a name, return type, and parameters. Functions can optionally return values using the return statement. 3) Functions improve code readability and maintainability by separating a program into smaller, well-defined units. Parameters allow functions to accept input values, while return values allow functions to return results.

Uploaded by

Prakhar Billore
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/ 137

C++ Functions

A function is a block of code that performs a specific task.


 Suppose we need to create a program to create a circle
and color it. We can create two functions to solve this
problem:
a function to draw the circle
a function to color the circle
 Dividing a complex problem into smaller chunks makes
our program easy to understand and reusable.

There are two types of function:

1. Standard Library Functions: Predefined in C++

2. User-defined Function: Created by users

C++ User-defined Function

C++ allows the programmer to define their own function.


A user-defined function groups code to perform a specific task
and that group of code is given a name (identifier).

When the function is invoked from any part of the program, it all
executes the codes defined in the body of the function.

C++ Function Declaration

The syntax to declare a function is:

returnType functionName (parameter1, parameter2,...)


{
// function body
}
Here's an example of a function declaration.

void greet() // function declaration

{
cout << "Hello World";
}
Here,
 the name of the function is greet()
 the return type of the function is void
 the empty parentheses mean it doesn't have any
parameters
 the function body is written inside {}
Note: We will learn about returnType and parameters later in
this tutorial.

Calling a Function

In the above program, we have declared a function


named greet(). To use the greet() function, we need to call it.
Here's how we can call the above greet() function.

void main()
{

greet(); // calling a function

}
How Function works in C++

Example 1: Display a Text


#include <iostream>
#include<conio.h>

void greet() // declaring a function

{
cout << "Hello there!";
}

void main()
{

greet(); // calling the function

getch();
}

Output
Hello there!
Function Parameters

As mentioned above, a function can be declared with


parameters (arguments). A parameter is a value that is passed
when declaring a function.

For example, let us consider the function below:

void printNum(int num)


{
cout << num;
}
Here, the int variable num is the function parameter.
We pass a value to the function parameter while calling the
function.
Void main()
{
int n = 7;

// calling the function


// n is passed to the function as argument
printNum(n);

getch();
}
Example 2: Function with Parameters
// program to print a text

#include <iostream.h>
#include<conio.h>
void displayNum(int n1, float n2) // display a number
{
cout << "The int number is " << n1;
cout << "The double number is " << n2;
}
void main()
{
int num1 = 5;
double num2 = 5.5;
displayNum(num1, num2); // calling the function

getch();
}
Output
The int number is 5
The double number is 5.5

In the above program, we have used a function that has


one int parameter and one double parameter.
We then pass num1 and num2 as arguments. These values are
stored by the function parameters n1 and n2 respectively.
C++ function with parameters
Note: The type of the arguments passed while calling the
function must match with the corresponding parameters defined
in the function declaration.

Return Statement

In the above programs, we have used void in the function


declaration. For example,

void displayNumber()
{
// code
}
This means the function is not returning any value.
It's also possible to return a value from a function. For this, we
need to specify the returnType of the function during function
declaration.

Then, the return statement can be used to return a value from a


function.

For example,
int add (int a, int b)
{
return (a + b);
}
Here, we have the data type int instead of void. This means
that the function returns an int value.
The code return (a + b); returns the sum of the two parameters
as the function value.
The return statement denotes that the function has ended. Any
code after return inside the function is not executed.
Example 3: Add Two Numbers
// program to add two numbers using a function

#include <iostream>

using namespace std;

// declaring a function
int add(int a, int b)
{
return (a + b);
}

int main()
{

int sum;

// calling the function and storing


// the returned value in sum
sum = add(100, 78);

cout << "100 + 78 = " << sum << endl;

return 0;
}
Output
100 + 78 = 178

In the above program, the add() function is used to find the sum
of two numbers.
We pass two int literals 100 and 78 while calling the function.
We store the returned value of the function in the variable sum,
and then we print it.
Working of C++ Function with return statement

Notice that sum is a variable of int type. This is because the


return value of add() is of int type.

Function Prototype

In C++, the code of function declaration should be before the


function call. However, if we want to define a function after the
function call, we need to use the function prototype. For
example,

// function prototype
void add(int, int);

void main()
{
// calling the function before declaration.
add(5, 3);
return 0;
}
// function definition
void add(int a, int b)
{
cout << (a + b);
}
In the above code, the function prototype is:
void add(int, int);

This provides the compiler with information about the function


name and its parameters. That's why we can use the code to
call a function before the function has been defined.
The syntax of a function prototype is:

returnType functionName(dataType1, dataType2, ...);

Example 4: C++ Function Prototype


// using function definition after main() function
// function prototype is declared before main()

#include <iostream.h>
#include<conio.h>
// function prototype
int add(int, int);
void main()
{
int sum;
sum = add(100, 78); // calling the function and storing
cout << "100 + 78 = " << sum << endl; // the returned value in sum

getch();
}

// function definition
int add(int a, int b)
{
return (a + b);
}
Output
100 + 78 = 178

The above program is nearly identical to Example 3. The only


difference is that here, the function is defined after the function
call.

That's why we have used a function prototype in this example.

Benefits of Using User-Defined Functions

 Functions make the code reusable. We can declare them


once and use them multiple times.
 Functions make the program easier as each small task is
divided into a function.
 Functions increase readability.

C++ Library Functions

Library functions are the built-in functions in C++ programming.


Programmers can use library functions by invoking the
functions directly; they don't need to write the functions
themselves.

Some common library functions in C++


are sqrt(), abs(), isdigit(), etc.

In order to use library functions, we usually need to include the


header file in which these library functions are defined.

For instance, in order to use mathematical functions such


as sqrt() and abs(), we need to include the header file cmath.
C++ User-defined Function Types
.user-defined functions can be categorised as:

1. Function with no argument and no return value


2. Function with no argument but return value
3. Function with argument but no return value
4. Function with argument and return value

Consider a situation in which you have to check prime


number. This problem is solved below by making user-
defined function in 4 different ways as mentioned above.

Example 1: No arguments passed and no return value


#include <iostream.h>
#include<conio.h>
void prime();

int main()
{
// No argument is passed to prime()
prime();
return 0;
}// Return type of function is void because value is not returned.
void prime()
{

int num, i, flag = 0;

cout << "Enter a positive integer enter to check: ";


cin >> num;

for(i = 2; i <= num/2; ++i)


{
if(num % i == 0)
{
flag = 1;
break;
}
}

if (flag == 1)
{
cout << num << " is not a prime number.";
}
else
{
cout << num << " is a prime number.";
}
}
In the above program, prime() is called from the main() with no
arguments.
prime() takes the positive number from the user and checks
whether the number is a prime number or not.
Since, return type of prime() is void, no value is returned from
the function.

Example 2: No arguments passed but a return value


#include <iostream.h>
#include<conio.h>
int prime();

int main()
{
int num, i, flag = 0;

// No argument is passed to prime()


num = prime();
for (i = 2; i <= num/2; ++i)
{
if (num%i == 0)
{
flag = 1;
break;
}
}

if (flag == 1)
{
cout<<num<<" is not a prime number.";
}
else
{
cout<<num<<" is a prime number.";
}
return 0;
}// Return type of function is int
int prime()
{
int n;

printf("Enter a positive integer to check: ");


cin >> n;

return n;
}
In the above program, prime() function is called from
the main() with no arguments.
prime() takes a positive integer from the user. Since, return
type of the function is an int, it returns the inputted number from
the user back to the calling main() function.
Then, whether the number is prime or not is checked in the
main() itself and printed onto the screen.

Example 3: Arguments passed but no return value


#include <iostream.h>
#include<conio.h>
void prime(int n);

int main()
{
int num;
cout << "Enter a positive integer to check: ";
cin >> num;

// Argument num is passed to the function prime()


prime(num);
return 0;
}

// There is no return value to calling function. Hence, return type


of function is void. */
void prime(int n)
{
int i, flag = 0;
for (i = 2; i <= n/2; ++i)
{
if (n%i == 0)
{
flag = 1;
break;
}
}

if (flag == 1)
{
cout << n << " is not a prime number.";
}
else {
cout << n << " is a prime number.";
}
}
In the above program, positive number is first asked from the
user which is stored in the variable num.
Then, num is passed to the prime() function where, whether the
number is prime or not is checked and printed.
Since, the return type of prime() is a void, no value is returned
from the function.
Example 4: Arguments passed and a return value.
#include <iostream.h>
#include<conio.h>
int prime(int n);

void main()
{
int num, flag = 0;
cout << "Enter positive integer to check: ";
cin >> num;

// Argument num is passed to check() function


flag = prime(num);

if(flag == 1)
cout << num << " is not a prime number.";
else
cout<< num << " is a prime number.";
getch();
}

/* This function returns integer value. */


int prime(int n)
{
int i;
for(i = 2; i <= n/2; ++i)
{
if(n % i == 0)
return 1;
}

return 0;
}
In the above program, a positive integer is asked from the user
and stored in the variable num.
Then, num is passed to the function prime() where, whether the
number is prime or not is checked.
Since, the return type of prime() is an int, 1 or 0 is returned to
the main() calling function. If the number is a prime number, 1
is returned. If not, 0 is returned.
Back in the main() function, the returned 1 or 0 is stored in the
variable flag, and the corresponding text is printed onto the
screen.

Example 5: C++ Program to Find the Square Root of a Number


#include <iostream.h>
#include <cmath.h>
#include<conio.h>

void main()
{
double number, squareRoot;
number = 25.0;
// sqrt() is a library function to calculate the square root
squareRoot = sqrt(number);

cout << "Square root of " << number << " = " << squareRoot;

getch();
}
Output
Square root of 25 = 5

In this program, the sqrt() library function is used to calculate


the square root of a number.
The function declaration of sqrt() is defined in the cmath header
file. That's why we need to use the code #include <cmath> to
use the sqrt() function.
C++ Multidimensional Arrays

In this tutorial, we'll learn about multi-dimensional arrays in


C++. More specifically, how to declare them, access them, and
use them efficiently in our program.
In C++, we can create an array of an array, known as a
multidimensional array. For example:
int x[3][4];
Here, x is a two-dimensional array. It can hold a maximum of
12 elements.
We can think of this array as a table with 3 rows and each row
has 4 columns as shown below.

Elements in two-dimensional array in C++ Programming.

1. Initialization of two-dimensional array

int test[2][3] = {2, 4, 5, 9, 0, 19};

The above method is not preferred. A better way to initialize


this array with the same array elements is given below:

int test [2][3] = { {2, 4, 5}, {9, 0, 19}};

This array has 2 rows and 3 columns, which is why we have


two rows of elements with 3 elements each.
The second dimension has the value
Example 1: Two Dimensional Array

// C++ Program to display all elements


// of an initialised two dimensional array

#include <iostream.h>
#include<conio.h>
Void main()
{
int test[3][2] = {{2, -5},{4, 0},{9, 1}};
// use of nested for loop
// access rows of the array
for (int i = 0; i < 3; ++i)
{
// access columns of the array
for (int j = 0; j < 2; ++j)
{
cout << "test[" << i << "][" << j << "] = " << test[i][j] << endl;
}
}

getch();
}
Run Code
Output
test[0][0] = 2
test[0][1] = -5
test[1][0] = 4
test[1][1] = 0
test[2][0] = 9
test[2][1] = 1
In the above example, we have initialized a two-
dimensional int array named test that has 3 "rows" and 2
"columns".
Here, we have used the nested for loop to display the array
elements.
the outer loop from i == 0 to i == 2 access the rows of the
array
the inner loop from j == 0 to j == 1 access the columns of the
array
Finally, we print the array elements in each iteration.

Example 2: Taking Input for Two Dimensional Array


#include <iostream>
using namespace std;
#include <iostream.h>
#include<conio.h>
Void main()
{
int numbers[2][3];
cout << "Enter 6 numbers: " << endl;
// Storing user input in the array
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 3; ++j)
{
cin >> numbers[i][j];
}
}
cout << "The numbers are: " << endl;
// Printing array elements
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 3; ++j)
{
cout << "numbers[" << i << "][" << j << "]: " <<
numbers[i][j] << endl;
}
}
getch()
}
Run Code
Output
Enter 6 numbers:
1
2
3
4
5
6
The numbers are:
numbers[0][0]: 1
numbers[0][1]: 2
numbers[0][2]: 3
numbers[1][0]: 4
numbers[1][1]: 5
numbers[1][2]: 6
Passing Array to a Function in C++ Programming
In this tutorial, we will learn how to pass a single-dimensional
and multidimensional array as a function parameter in C++
with the help of examples.

In C++, we can pass arrays as an argument to a function.


And, also we can return arrays from a function.

Before you learn about passing arrays as a function


argument, make sure you know about C++ Arrays and C++
Functions.

Syntax for Passing Arrays as Function Parameters


The syntax for passing an array to a function is:

returnType functionName(dataType arrayName[arraySize])


{
// code
}

Let's see an example,


int total(int marks[5])
{
// code
}
Here, we have passed an int type array named marks to the
function total(). The size of the array is 5.

Example 1: Passing One-dimensional Array to a Function


// C++ Program to display marks of 5 students

#include <iostream.h>
#include<conio.h>
Void main()
{
// declare function to display marks
// take a 1d array as parameter
void display(int m[5])
{
cout << "Displaying marks: " << endl;

// display array elements


for (int i = 0; i < 5; ++i) {
cout << "Student " << i + 1 << ": " << m[i] << endl;
}
}

Void main()
{

// declare and initialize an array


int marks[5] = {88, 76, 90, 61, 69};
// call display function
// pass array as argument
display(marks);

getch();
}
Run Code
Output
Displaying marks:
Student 1: 88
Student 2: 76
Student 3: 90
Student 4: 61
Student 5: 69
Here,
When we call a function by passing an array as the
argument, only the name of the array is used.
display(marks);
Here, the argument marks represent the memory address of
the first element of array marks[5].
However, notice the parameter of the display() function.
void display(int m[5])
Here, we use the full declaration of the array in the function
parameter, including the square braces [].
The function parameter int m[5] converts to int* m;. This
points to the same address pointed by the array marks. This
means that when we manipulate m[5] in the function body,
we are actually manipulating the original array marks.

C++ handles passing an array to a function in this way to


save memory and time.

C++ Structs
In C++, classes and structs are blueprints that are used to
create the instance of a class. Structs are used for
lightweight objects such as Rectangle, color, Point, etc.

Unlike class, structs in C++ are value type than reference


type. It is useful if you have data that is not intended to be
modified after creation of struct.

C++ Structure is a collection of different data types. It is


similar to the class that holds different types of data.
The Syntax Of Structure
struct structure_name
{
// member declarations.
}
In the above declaration, a structure is declared by preceding
the struct keyword followed by the identifier(structure
name). Inside the curly braces, we can declare the member
variables of different types. Consider the following
situation:
struct Student
{
char name[20];
int id;
int age;
}
In the above case, Student is a structure contains three
variables name, id, and age. When the structure is declared,
no memory is allocated. When the variable of a structure is
created, then the memory is allocated. Let's understand this
scenario.

How to create the instance of Structure?

Structure variable can be defined as:

Student s;

Here, s is a structure variable of type Student. When the


structure variable is created, the memory will be allocated.
Student structure contains one char variable and two integer
variable. Therefore, the memory for one char variable is 1
byte and two ints will be 2*4 = 8. The total memory occupied
by the s variable is 9 byte.

How to access the variable of Structure:

The variable of the structure can be accessed by simply


using the instance of the structure followed by the dot (.)
operator and then the field of the structure.

For example:
s.id = 4;

In the above statement, we are accessing the id field of the


structure Student by using the dot(.) operator and assigns
the value 4 to the id field.
C++ Struct Example

simple example of struct Rectangle which has two data


members width and height.
#include <iostream.h>
#include<conio.h>
struct Rectangle
{
int width, height;
};
void main()
{
struct Rectangle rec;
rec.width=8;
rec.height=5;
cout<<"Area of Rectangle is: "<<(rec.width * rec.height)<<endl;
getch();
}
Output:

Area of Rectangle is: 40

Data Structure and Types


What are Data Structures?

Data structure is a storage that is used to store and organize data. It is a


way of arranging data on a computer so that it can be accessed and
updated efficiently.
Depending on your requirement and project, it is important to choose the
right data structure for your project. For example, if you want to store data
sequentially in the memory, then you can go for the Array data structure.

Array data Structure Representation

Types of Data Structure

Basically, data structures are divided into two categories:

 Linear data structure

 Non-linear data structure

Linear data structures

In linear data structures, the elements are arranged in sequence one after
the other. Since elements are arranged in particular order, they are easy to
implement.

However, when the complexity of the program increases, the linear data
structures might not be the best choice because of operational
complexities.
Popular linear data structures are:
1. Array Data Structure

In an array, elements in memory are arranged in continuous memory. All


the elements of an array are of the same type. And, the type of elements
that can be stored in the form of arrays is determined by the programming
language.

To learn more, visit Java Array.

An array with each element represented by an index

2. Stack Data Structure

In stack data structure, elements are stored in the LIFO principle. That is,
the last element stored in a stack will be removed first.

It works just like a pile of plates where the last plate kept on the pile will be
removed first. To learn more, visit Stack Data Structure.

In a stack, operations can be perform only from one end (top here).
3. Queue Data Structure

Unlike stack, the queue data structure works in the FIFO principle where
first element stored in the queue will be removed first.

It works just like a queue of people in the ticket counter where first person
on the queue will get the ticket first. To learn more, visit Queue Data
Structure.

In a queue, addition and removal are


performed from separate ends.

4. Linked List Data Structure

In linked list data structure, data elements are connected through a series
of nodes. And, each node contains the data items and address to the next
node.

To learn more, visit Linked List Data Structure.

A linked list
Non linear data structures

Unlike linear data structures, elements in non-linear data structures are not
in any sequence. Instead they are arranged in a hierarchical manner where
one element will be connected to one or more elements.

Non-linear data structures are further divided into graph and tree based
data structures.

1. Graph Data Structure

In graph data structure, each node is called vertex and each vertex is
connected to other vertices through edges.

To learn more, visit Graph Data Structure.

Graph data structure example

2. Trees Data Structure

Similar to a graph, a tree is also a collection of vertices and edges.


However, in tree data structure, there can only be one edge between two
vertices.

To learn more, visit Tree Data Structure.


Tree data structure example

Linear Vs Non-linear Data Structures

Now that we know about linear and non-linear data structures, let's see the
major differences between them.

Linear Data Structures Non Linear Data Structures

The data items are arranged in sequential The data items are arranged in non-
order, one after the other. sequential order (hierarchical manner).

All the items are present on the single The data items are present at different
layer. layers.

It can be traversed on a single run. That is, It requires multiple runs. That is, if we
if we start from the first element, we can start from the first element it might not
traverse all the elements sequentially in a be possible to traverse all the elements
single pass. in a single pass.

Different structures utilize memory in


The memory utilization is not efficient. different efficient ways depending on
the need.

The time complexity increase with the data Time complexity remains the same.
size.

Example: Arrays, Stack, Queue Example: Tree, Graph, Map

What is Data Structure?


Whenever we want to work with a large amount of data, then organizing that data is very
important. If that data is not organized effectively, it is very difficult to perform any task on that
data. If it is organized effectively then any operation can be performed easily on that data.
A data structure can be defined as follows...

Data structure is a method of organizing a large amount of data more efficiently so that
any operation on that data becomes easy

Based on the organizing method of data structure, data structures are divided into two types.

 Linear Data Structures


 Non - Linear Data Structures

Linear Data Structures


If a data structure organizes the data in sequential order, then that data structure is called
a Linear Data Structure.

Example
1. Arrays
2. List (Linked List)
3. Stack
4. Queue

Non - Linear Data Structures


If a data structure organizes the data in random order, then that data structure is called as
Non-Linear Data Structure.

Example
1. Tree
2. Graph
3. Dictionaries
4. Heaps
5. Tries, Etc.,
What is a Stack?
Stack is a linear data structure in which the insertion and deletion operations are performed at
only one end. In a stack, adding and removing of elements are performed at a single position
which is known as "top". That means, a new element is added at top of the stack and an element
is removed from the top of the stack. In stack, the insertion and deletion operations are
performed based on LIFO (Last In First Out) principle.

In a stack, the insertion operation is performed using a function


called "push" and deletion operation is performed using a
function called "pop".

In the figure, PUSH and POP operations are performed at a top


position in the stack. That means, both the insertion and
deletion operations are performed at one end (i.e., at Top)

A stack data structure can be defined as follows...


Stack is a linear data structure in which the operations are
performed based on LIFO principle.
Stack can also be defined as
"A Collection of similar data items in which both insertion and
deletion operations are performed based on LIFO principle".
Example
If we want to create a stack by inserting 10,45,12,16,35 and 50.
Then 10 becomes the bottom-most element and 50 is the
topmost element. The last inserted element 50 is at Top of the
stack as shown in the image below...

Operations on a Stack
The following operations are performed on the stack...

1. Push (To insert an element on to the stack)


2. Pop (To delete an element from the stack)
3. Display (To display elements of the stack)

Stack data structure can be implemented in two ways. They are


as follows...

1. Using Array
2. Using Linked List

When a stack is implemented using an array, that stack can


organize an only limited number of elements. When a stack is
implemented using a linked list, that stack can organize an
unlimited number of elements.
Stack Using Array
A stack data structure can be implemented using a one-
dimensional array. But stack implemented using array stores
only a fixed number of data values. This implementation is very
simple. Just define a one dimensional array of specific size and
insert or delete the values into that array by using LIFO
principle with the help of a variable called 'top'. Initially, the top
is set to -1. Whenever we want to insert a value into the stack,
increment the top value by one and then insert. Whenever we
want to delete a value from the stack, then delete the top value
and decrement the top value by one.

Stack Operations using Array


A stack can be implemented using array as follows...

Before implementing actual operations, first follow the below


steps to create an empty stack.

 Step 1 - Include all the header files which are used in the
program and define a constant 'SIZE' with specific value.
 Step 2 - Declare all the functions used in stack
implementation.
 Step 3 - Create a one dimensional array with fixed size (int
stack[SIZE])
 Step 4 - Define a integer variable 'top' and initialize with '-
1'. (int top = -1)
 Step 5 - In main method, display menu with list of
operations and make suitable function calls to perform
operation selected by the user on the stack.
push(value) - Inserting value into the stack

In a stack, push() is a function used to insert an element into


the stack. In a stack, the new element is always inserted
at top position. Push function takes one integer value as
parameter and inserts that value into the stack. We can use the
following steps to push an element on to the stack...

 Step 1 - Check whether stack is FULL. (top == SIZE-1)


 Step 2 - If it is FULL, then display "Stack is FULL!!! Insertion is
not possible!!!" and terminate the function.
 Step 3 - If it is NOT FULL, then increment top value by one
(top++) and set stack[top] to value (stack[top] = value).

pop() - Delete a value from the Stack

In a stack, pop() is a function used to delete an element from


the stack. In a stack, the element is always deleted
from top position. Pop function does not take any value as
parameter. We can use the following steps to pop an element
from the stack...

 Step 1 - Check whether stack is EMPTY. (top == -1)


 Step 2 - If it is EMPTY, then display "Stack is EMPTY!!!
Deletion is not possible!!!" and terminate the function.
 Step 3 - If it is NOT EMPTY, then delete stack[top] and
decrement top value by one (top--).

display() - Displays the elements of a Stack

We can use the following steps to display the elements of a


stack...
 Step 1 - Check whether stack is EMPTY. (top == -1)
 Step 2 - If it is EMPTY, then display "Stack is EMPTY!!!" and
terminate the function.
 Step 3 - If it is NOT EMPTY, then define a variable 'i' and
initialize with top. Display stack[i] value and
decrement i value by one (i--).
 Step 3 - Repeat above step until i value becomes '0'.
Expressions

What is an Expression?

In any programming language, if we want to perform any


calculation or to frame a condition etc., we use a set of symbols
to perform the task. These set of symbols makes an
expression.

An expression can be defined as follows...

An expression is a collection of operators and operands that


represents a specific value.

In above definition, operator is a symbol which performs a


particular task like arithmetic operation or logical operation or
conditional operation etc.,

Operands are the values on which the operators can perform


the task. Here operand can be a direct value or variable or
address of memory location.

Expression Types

Based on the operator position, expressions are divided into


THREE types. They are as follows...

Infix Expression

Postfix Expression

Prefix Expression

Infix Expression
In infix expression, operator is used in between the operands.

The general structure of an Infix expression is as follows...

Operand1 Operator Operand2

Example

Postfix Expression

In postfix expression, operator is used after operands. We can


say that "Operator follows the Operands".

The general structure of Postfix expression is as follows...

Operand1 Operand2 Operator

Example
Prefix Expression

In prefix expression, operator is used before operands. We can


say that "Operands follows the Operator".

The general structure of Prefix expression is as follows...

Operator Operand1 Operand2

Example

Every expression can be represented using all the above three


different types of expressions. And we can convert an
expression from one form to another form like Infix to
Postfix, Infix to Prefix, Prefix to Postfix and vice versa.

Infix to Postfix Conversion

Any expression can be represented using three types of


expressions (Infix, Postfix, and Prefix). We can also convert
one type of expression to another type of expression like Infix
to Postfix, Infix to Prefix, Postfix to Prefix and vice versa.

To convert any Infix expression into Postfix or Prefix expression


we can use the following procedure...
Find all the operators in the given Infix Expression.

Find the order of operators evaluated according to their


Operator precedence.

Convert each operator into required type of expression (Postfix


or Prefix) in the same order.

Example

Consider the following Infix Expression to be converted into


Postfix Expression...

D=A+B*C

Step 1 - The Operators in the given Infix Expression : = , + , *

Step 2 - The Order of Operators according to their preference : *


,+,=

Step 3 - Now, convert the first operator * ----- D = A + B C *

Step 4 - Convert the next operator + ----- D = A BC* +

Step 5 - Convert the next operator = ----- D ABC*+ =

Finally, given Infix Expression is converted into Postfix


Expression as follows...

DABC*+=

Infix to Postfix Conversion using Stack Data Structure

To convert Infix Expression into Postfix Expression using a


stack data structure, We can use the following steps...
Read all the symbols one by one from left to right in the given
Infix Expression.

If the reading symbol is operand, then directly print it to the


result (Output).

If the reading symbol is left parenthesis '(', then Push it on to


the Stack.

If the reading symbol is right parenthesis ')', then Pop all the
contents of stack until respective left parenthesis is poped and
print each poped symbol to the result.

If the reading symbol is operator (+ , - , * , / etc.,), then Push it on


to the Stack. However, first pop the operators which are already
on the stack that have higher or equal precedence than current
operator and print them to the result.

Example

Consider the following Infix Expression...

(A+B)*(C-D)

The given infix expression can be converted into postfix


expression using Stack data Structure as follows...
The final Postfix Expression is as follows...

AB+CD-*

Postfix Expression Evaluation


A postfix expression is a collection of operators and operands in which the operator is placed

after the operands. That means, in a postfix expression the operator follows the operands.

Postfix Expression has following general structure...

Operand1 Operand2 Operator

Example

Postfix Expression Evaluation using Stack Data Structure

A postfix expression can be evaluated using the Stack data structure. To evaluate a postfix

expression using Stack data structure we can use the following steps...

1. Read all the symbols one by one from left to right in the given Postfix Expression

2. If the reading symbol is operand, then push it on to the Stack.

3. If the reading symbol is operator (+ , - , * , / etc.,), then perform TWO pop

operations and store the two popped oparands in two different variables (operand1

and operand2). Then perform reading symbol operation using operand1 and

operand2 and push result back on to the Stack.

4. Finally! perform a pop operation and display the popped value as final result.
Example

Consider the following Expression...


Queue ADT
What is a Queue?

Queue is a linear data structure in which the insertion and deletion


operations are performed at two different ends. In a queue data
structure, adding and removing elements are performed at two different
positions. The insertion is performed at one end and deletion is
performed at another end. In a queue data structure, the insertion
operation is performed at a position which is known as 'rear' and the
deletion operation is performed at a position which is known as 'front'. In
queue data structure, the insertion and deletion operations are
performed based on FIFO (First In First Out) principle.

In a queue data structure, the insertion operation is performed using a


function called "enQueue()" and deletion operation is performed using a
function called "deQueue()".

Queue data structure can be defined as follows...

Queue data structure is a linear data structure in which the operations


are performed based on FIFO principle.

A queue data structure can also be defined as


"Queue data structure is a collection of similar data items in which
insertion and deletion operations are performed based on FIFO
principle".

Example

Queue after inserting 25, 30, 51, 60 and 85.

Operations on a Queue

The following operations are performed on a queue data structure...

enQueue(value) - (To insert an element into the queue)

deQueue() - (To delete an element from the queue)

display() - (To display the elements of the queue)

Queue data structure can be implemented in two ways. They are as


follows...

Using Array

Using Linked List

When a queue is implemented using an array, that queue can organize


an only limited number of elements. When a queue is implemented
using a linked list, that queue can organize an unlimited number of
elements.

Queue Datastructure Using Array


A queue data structure can be implemented using one dimensional
array. The queue implemented using array stores only fixed number of
data values. The implementation of queue data structure using array is
very simple. Just define a one dimensional array of specific size and
insert or delete the values into that array by using FIFO (First In First
Out) principle with the help of variables 'front' and 'rear'. Initially both
'front' and 'rear' are set to -1. Whenever, we want to insert a new value
into the queue, increment 'rear' value by one and then insert at that
position. Whenever we want to delete a value from the queue, then
delete the element which is at 'front' position and increment 'front' value
by one.

Queue Operations using Array

Queue data structure using array can be implemented as follows...

Before we implement actual operations, first follow the below steps to


create an empty queue.

Step 1 - Include all the header files which are used in the program and
define a constant 'SIZE' with specific value.

Step 2 - Declare all the user defined functions which are used in queue
implementation.

Step 3 - Create a one dimensional array with above defined SIZE (int
queue[SIZE])

Step 4 - Define two integer variables 'front' and 'rear' and initialize both
with '-1'. (int front = -1, rear = -1)
Step 5 - Then implement main method by displaying menu of operations
list and make suitable function calls to perform operation selected by the
user on queue.

enQueue(value) - Inserting value into the queue

In a queue data structure, enQueue() is a function used to insert a new


element into the queue. In a queue, the new element is always inserted
at rear position. The enQueue() function takes one integer value as a
parameter and inserts that value into the queue. We can use the
following steps to insert an element into the queue...

Step 1 - Check whether queue is FULL. (rear == SIZE-1)

Step 2 - If it is FULL, then display "Queue is FULL!!! Insertion is not


possible!!!" and terminate the function.

Step 3 - If it is NOT FULL, then increment rear value by one (rear++)


and set queue[rear] = value.

deQueue() - Deleting a value from the Queue

In a queue data structure, deQueue() is a function used to delete an


element from the queue. In a queue, the element is always deleted
from front position. The deQueue() function does not take any value as
parameter. We can use the following steps to delete an element from the
queue...

Step 1 - Check whether queue is EMPTY. (front == rear)

Step 2 - If it is EMPTY, then display "Queue is EMPTY!!! Deletion is not


possible!!!" and terminate the function.

Step 3 - If it is NOT EMPTY, then increment the front value by one (front
++). Then display queue[front] as deleted element. Then check whether
both front and rear are equal (front == rear), if it TRUE, then set
both front and rear to '-1' (front = rear = -1).

display() - Displays the elements of a Queue

We can use the following steps to display the elements of a queue...

Step 1 - Check whether queue is EMPTY. (front == rear)

Step 2 - If it is EMPTY, then display "Queue is EMPTY!!!" and terminate


the function.

Step 3 - If it is NOT EMPTY, then define an integer variable 'i' and set
'i = front+1'.

Step 4 - Display 'queue[i]' value and increment 'i' value by one (i++).
Repeat the same until 'i' value reaches to rear (i <= rear)

Circular Queue Datastructure

In a normal Queue Data Structure, we can insert elements until queue


becomes full. But once the queue becomes full, we can not insert the
next element until all the elements are deleted from the queue. For
example, consider the queue below...

The queue after inserting all the elements into it is as follows...

Now consider the following situation after deleting three elements from
the queue...
This situation also says that Queue is Full and we cannot insert the new
element because 'rear' is still at last position. In the above situation, even
though we have empty positions in the queue we can not make use of
them to insert the new element. This is the major problem in a normal
queue data structure. To overcome this problem we use a circular queue
data structure.

What is Circular Queue?

A Circular Queue can be defined as follows...

A circular queue is a linear data structure in which the operations are


performed based on FIFO (First In First Out) principle and the last
position is connected back to the first position to make a circle.

Graphical representation of a circular queue is as follows...

Implementation of Circular Queue

To implement a circular queue data structure using an array, we first


perform the following steps before we implement actual operations.
Step 1 - Include all the header files which are used in the program and
define a constant 'SIZE' with specific value.

Step 2 - Declare all user defined functions used in circular queue


implementation.

Step 3 - Create a one dimensional array with above defined SIZE (int
cQueue[SIZE])

Step 4 - Define two integer variables 'front' and 'rear' and initialize both
with '-1'. (int front = -1, rear = -1)

Step 5 - Implement main method by displaying menu of operations list


and make suitable function calls to perform operation selected by the
user on circular queue.

enQueue(value) - Inserting value into the Circular Queue

In a circular queue, enQueue() is a function which is used to insert an


element into the circular queue. In a circular queue, the new element is
always inserted at rear position. The enQueue() function takes one
integer value as parameter and inserts that value into the circular queue.
We can use the following steps to insert an element into the circular
queue...

Step 1 - Check whether queue is FULL. ((rear == SIZE-1 && front == 0)


|| (front == rear+1))

Step 2 - If it is FULL, then display "Queue is FULL!!! Insertion is not


possible!!!" and terminate the function.

Step 3 - If it is NOT FULL, then check rear == SIZE - 1 && front != 0 if it


is TRUE, then set rear = -1.
Step 4 - Increment rear value by one (rear++),
set queue[rear] = value and check 'front == -1' if it is TRUE, then
set front = 0.

deQueue() - Deleting a value from the Circular Queue

In a circular queue, deQueue() is a function used to delete an element


from the circular queue. In a circular queue, the element is always
deleted from front position. The deQueue() function doesn't take any
value as a parameter. We can use the following steps to delete an
element from the circular queue...

Step 1 - Check whether queue is EMPTY. (front == -1 && rear == -1)

Step 2 - If it is EMPTY, then display "Queue is EMPTY!!! Deletion is not


possible!!!" and terminate the function.

Step 3 - If it is NOT EMPTY, then display queue[front] as deleted


element and increment the front value by one (front ++). Then check
whether front == SIZE, if it is TRUE, then set front = 0. Then check
whether both front - 1 and rear are equal (front -1 == rear), if it TRUE,
then set both front and rear to '-1' (front = rear = -1).

display() - Displays the elements of a Circular Queue

We can use the following steps to display the elements of a circular


queue...

Step 1 - Check whether queue is EMPTY. (front == -1)

Step 2 - If it is EMPTY, then display "Queue is EMPTY!!!" and terminate


the function.

Step 3 - If it is NOT EMPTY, then define an integer variable 'i' and set
'i = front'.
Step 4 - Check whether 'front <= rear', if it is TRUE, then display
'queue[i]' value and increment 'i' value by one (i++). Repeat the same
until 'i <= rear' becomes FALSE.

Step 5 - If 'front <= rear' is FALSE, then display 'queue[i]' value and
increment 'i' value by one (i++). Repeat the same until'i <= SIZE - 1'
becomes FALSE.

Step 6 - Set i to 0.

Step 7 - Again display 'cQueue[i]' value and increment i value by one


(i++). Repeat the same until 'i <= rear' becomes FALSE.

Double Ended Queue Datastructure

Double Ended Queue is also a Queue data structure in which the


insertion and deletion operations are performed at both the ends
(front and rear). That means, we can insert at both front and rear
positions and can delete from both front and rear positions.

Double Ended Queue can be represented in TWO ways, those are as


follows...

Input Restricted Double Ended Queue

Output Restricted Double Ended Queue

Input Restricted Double Ended Queue


In input restricted double-ended queue, the insertion operation is
performed at only one end and deletion operation is performed at both
the ends.

Output Restricted Double Ended Queue

In output restricted double ended queue, the deletion operation is


performed at only one end and insertion operation is performed at both
the ends.

Tree - Terminology

In linear data structure data is organized in sequential order and in non-


linear data structure data is organized in random order. A tree is a very
popular non-linear data structure used in a wide range of applications. A
tree data structure can be defined as follows...

Tree is a non-linear data structure which organizes data in hierarchical


structure and this is a recursive definition.
A tree data structure can also be defined as follows...

Tree data structure is a collection of data (Node) which is organized in


hierarchical structure recursively

In tree data structure, every individual element is called as Node. Node


in a tree data structure stores the actual data of that particular element
and link to next element in hierarchical structure.

In a tree data structure, if we have N number of nodes then we can have


a maximum of N-1 number of links.

Example

Terminology

In a tree data structure, we use the following terminology...

1. Root

In a tree data structure, the first node is called as Root Node. Every tree
must have a root node. We can say that the root node is the origin of the
tree data structure. In any tree, there must be only one root node. We
never have multiple root nodes in a tree.
2. Edge

In a tree data structure, the connecting link between any two nodes is
called as EDGE. In a tree with 'N' number of nodes there will be a
maximum of 'N-1' number of edges.

3. Parent

In a tree data structure, the node which is a predecessor of any node is


called as PARENT NODE. In simple words, the node which has a branch
from it to any other node is called a parent node. Parent node can also
be defined as "The node which has child / children".

4. Child

In a tree data structure, the node which is descendant of any node is


called as CHILD Node. In simple words, the node which has a link from its
parent node is called as child node. In a tree, any parent node can have
any number of child nodes. In a tree, all the nodes except root are child
nodes.
5. Siblings

In a tree data structure, nodes which belong to same Parent are called
as SIBLINGS. In simple words, the nodes with the same parent are called
Sibling nodes.

6. Leaf

In a tree data structure, the node which does not have a child is called
as LEAF Node. In simple words, a leaf is a node with no child.

In a tree data structure, the leaf nodes are also called as External Nodes.
External node is also a node with no child. In a tree, leaf node is also
called as 'Terminal' node.
7. Internal Nodes

In a tree data structure, the node which has atleast one child is called
as INTERNAL Node. In simple words, an internal node is a node with
atleast one child.

In a tree data structure, nodes other than leaf nodes are called
as Internal Nodes. The root node is also said to be Internal Node if the tree
has more than one node. Internal nodes are also called as 'Non-Terminal'
nodes.
8. Degree

In a tree data structure, the total number of children of a node is called


as DEGREE of that Node. In simple words, the Degree of a node is total
number of children it has. The highest degree of a node among all the
nodes in a tree is called as 'Degree of Tree'

9. Level

In a tree data structure, the root node is said to be at Level 0 and the
children of root node are at Level 1 and the children of the nodes which
are at Level 1 will be at Level 2 and so on... In simple words, in a tree
each step from top to bottom is called as a Level and the Level count
starts with '0' and incremented by one at each level (Step).
10. Height

In a tree data structure, the total number of edges from leaf node to a
particular node in the longest path is called as HEIGHT of that Node. In a
tree, height of the root node is said to be height of the tree. In a
tree, height of all leaf nodes is '0'.

11. Depth

In a tree data structure, the total number of egdes from root node to a
particular node is called as DEPTH of that Node. In a tree, the total
number of edges from root node to a leaf node in the longest path is said
to be Depth of the tree. In simple words, the highest depth of any leaf
node in a tree is said to be depth of that tree. In a tree, depth of the root
node is '0'.

12. Path

In a tree data structure, the sequence of Nodes and Edges from one
node to another node is called as PATH between that two Nodes. Length
of a Path is total number of nodes in that path. In below example the path
A - B - E - J has length 4.
13. Sub Tree

In a tree data structure, each child from a node forms a subtree


recursively. Every child node will form a subtree on its parent node.

ree Representations

A tree data structure can be represented in two methods. Those


methods are as follows...

List Representation

Left Child - Right Sibling Representation

Consider the following tree...


1. List Representation

In this representation, we use two types of nodes one for representing


the node with data called 'data node' and another for representing only
references called 'reference node'. We start with a 'data node' from the
root node in the tree. Then it is linked to an internal node through a
'reference node' which is further linked to any other node directly. This
process repeats for all the nodes in the tree.

The above example tree can be represented using List representation as


follows...
2. Left Child - Right Sibling Representation

In this representation, we use a list with one type of node which consists
of three fields namely Data field, Left child reference field and Right
sibling reference field. Data field stores the actual value of a node, left
reference field stores the address of the left child and right reference
field stores the address of the right sibling node. Graphical
representation of that node is as follows...

In this representation, every node's data field stores the actual value of
that node. If that node has left a child, then left reference field stores the
address of that left child node otherwise stores NULL. If that node has
the right sibling, then right reference field stores the address of right
sibling node otherwise stores NULL.
The above example tree can be represented using Left Child - Right
Sibling representation as follows...
Binary Tree Datastructure

In a normal tree, every node can have any number of children. A binary
tree is a special type of tree data structure in which every node can have
a maximum of 2 children. One is known as a left child and the other is
known as right child.

A tree in which every node can have a maximum of two children is called
Binary Tree.

In a binary tree, every node can have either 0 children or 1 child or 2


children but not more than 2 children.

Example
There are different types of binary trees and they are...

1. Strictly Binary Tree

In a binary tree, every node can have a maximum of two children. But in
strictly binary tree, every node should have exactly two children or none.
That means every internal node must have exactly two children. A
strictly Binary Tree can be defined as follows...

A binary tree in which every node has either two or zero number of
children is called Strictly Binary Tree

Strictly binary tree is also called as Full Binary Tree or Proper Binary
Tree or 2-Tree
Strictly binary tree data structure is used to represent mathematical
expressions.

Example

2. Complete Binary Tree

In a binary tree, every node can have a maximum of two children. But in
strictly binary tree, every node should have exactly two children or none
and in complete binary tree all the nodes must have exactly two children
and at every level of complete binary tree there must be 2level number
of nodes. For example at level 2 there must be 22 = 4 nodes and at level
3 there must be 23 = 8 nodes.

A binary tree in which every internal node has exactly two children and
all leaf nodes are at same level is called Complete Binary Tree.

Complete binary tree is also called as Perfect Binary Tree

3. Extended Binary Tree

A binary tree can be converted into Full Binary tree by adding dummy
nodes to existing nodes wherever required.

The full binary tree obtained by adding dummy nodes to a binary tree is
called as Extended Binary Tree.
In above figure, a normal binary tree is converted into full binary tree by
adding dummy nodes (In pink colour).

Binary Tree Representations

A binary tree data structure is represented using two methods. Those


methods are as follows...

Array Representation

Linked List Representation

Consider the following binary tree...


1. Array Representation of Binary Tree

In array representation of a binary tree, we use one-dimensional array


(1-D Array) to represent a binary tree.
Consider the above example of a binary tree and it is represented as
follows...

To represent a binary tree of depth 'n' using array representation, we


need one dimensional array with a maximum size of 2n + 1.

2. Linked List Representation of Binary Tree

We use a double linked list to represent a binary tree. In a double linked


list, every node consists of three fields. First field for storing left child
address, second for storing actual data and third for storing right child
address.
In this linked list representation, a node has the following structure...
The above example of the binary tree represented using Linked list
representation is shown as follows...
Binary Tree Traversals

When we wanted to display a binary tree, we need to follow some order


in which all the nodes of that binary tree must be displayed. In any
binary tree, displaying order of nodes depends on the traversal method.

Displaying (or) visiting order of nodes in a binary tree is called as Binary


Tree Traversal.

There are three types of binary tree traversals.

In - Order Traversal

Pre - Order Traversal

Post - Order Traversal

Consider the following binary tree...

1. In - Order Traversal ( leftChild - root - rightChild )

In In-Order traversal, the root node is visited between the left child and
right child. In this traversal, the left child node is visited first, then the root
node is visited and later we go for visiting the right child node. This in-
order traversal is applicable for every root node of all subtrees in the
tree. This is performed recursively for all nodes in the tree.
In the above example of a binary tree, first we try to visit left child of root
node 'A', but A's left child 'B' is a root node for left subtree. so we try to
visit its (B's) left child 'D' and again D is a root for subtree with nodes D, I
and J. So we try to visit its left child 'I' and it is the leftmost child. So first
we visit 'I' then go for its root node 'D' and later we visit D's right child 'J'.
With this we have completed the left part of node B. Then visit 'B' and
next B's right child 'F' is visited. With this we have completed left part of
node A. Then visit root node 'A'. With this we have completed left and
root parts of node A. Then we go for the right part of the node A. In right
of A again there is a subtree with root C. So go for left child of C and
again it is a subtree with root G. But G does not have left part so we
visit 'G' and then visit G's right child K. With this we have completed the
left part of node C. Then visit root node 'C' and next visit C's right
child 'H' which is the rightmost child in the tree. So we stop the process.

That means here we have visited in the order of I - D - J - B - F - A - G - K - C


- H using In-Order Traversal.

In-Order Traversal for above example of binary tree is

I-D-J-B-F-A-G-K-C-H

2. Pre - Order Traversal ( root - leftChild - rightChild )

In Pre-Order traversal, the root node is visited before the left child and
right child nodes. In this traversal, the root node is visited first, then its
left child and later its right child. This pre-order traversal is applicable for
every root node of all subtrees in the tree.
In the above example of binary tree, first we visit root node 'A' then visit
its left child 'B' which is a root for D and F. So we visit B's left
child 'D' and again D is a root for I and J. So we visit D's left
child 'I' which is the leftmost child. So next we go for visiting D's right
child 'J'. With this we have completed root, left and right parts of node D
and root, left parts of node B. Next visit B's right child 'F'. With this we
have completed root and left parts of node A. So we go for A's right
child 'C' which is a root node for G and H. After visiting C, we go for its
left child 'G' which is a root for node K. So next we visit left of G, but it
does not have left child so we go for G's right child 'K'. With this, we have
completed node C's root and left parts. Next visit C's right child 'H' which
is the rightmost child in the tree. So we stop the process.

That means here we have visited in the order of A-B-D-I-J-F-C-G-K-H using


Pre-Order Traversal.

Pre-Order Traversal for above example binary tree is

A-B-D-I-J-F-C-G-K-H

3. Post - Order Traversal ( leftChild - rightChild - root )

In Post-Order traversal, the root node is visited after left child and right
child. In this traversal, left child node is visited first, then its right child
and then its root node. This is recursively performed until the right most
node is visited.

Here we have visited in the order of I - J - D - F - B - K - G - H - C - A using


Post-Order Traversal.
Post-Order Traversal for above example binary tree is

I-J-D-F-B-K-G-H-C-A

Threaded Binary Trees

A binary tree can be represented using array representation or linked list


representation. When a binary tree is represented using linked list
representation, the reference part of the node which doesn't have a child
is filled with a NULL pointer. In any binary tree linked list representation,
there is a number of NULL pointers than actual pointers. Generally, in
any binary tree linked list representation, if there are 2N number of
reference fields, then N+1 number of reference fields are filled with NULL
( N+1 are NULL out of 2N ). This NULL pointer does not play any role
except indicating that there is no link (no child).

A. J. Perlis and C. Thornton have proposed new binary tree called


"Threaded Binary Tree", which makes use of NULL pointers to improve its
traversal process. In a threaded binary tree, NULL pointers are replaced
by references of other nodes in the tree. These extra references are
called as threads.

Threaded Binary Tree is also a binary tree in which all left child pointers
that are NULL (in Linked list representation) points to its in-order
predecessor, and all right child pointers that are NULL (in Linked list
representation) points to its in-order successor.

If there is no in-order predecessor or in-order successor, then it points to


the root node.

Consider the following binary tree...


To convert the above example binary tree into a threaded binary tree,
first find the in-order traversal of that tree...

In-order traversal of above binary tree...

H-D-I-B-E-A-F-J-C-G

When we represent the above binary tree using linked list


representation, nodes H, I, E, F, J and G left child pointers are NULL. This
NULL is replaced by address of its in-order predecessor respectively (I
to D, E to B, F to A, J to F and G to C), but here the node H does not
have its in-order predecessor, so it points to the root node A. And
nodes H, I, E, J and G right child pointers are NULL. These NULL pointers
are replaced by address of its in-order successor respectively (H to D, I
to B, E to A, and J to C), but here the node G does not have its in-order
successor, so it points to the root node A.
Above example binary tree is converted into threaded binary tree as
follows.

In the above figure, threads are indicated with dotted links.

Max Heap Datastructure

Heap data structure is a specialized binary tree-based data structure.


Heap is a binary tree with special characteristics. In a heap data
structure, nodes are arranged based on their values. A heap data
structure some times also called as Binary Heap.

There are two types of heap data structures and they are as follows...

Max Heap

Min Heap

Every heap data structure has the following properties...


Property #1 (Ordering): Nodes must be arranged in an order according to
their values based on Max heap or Min heap.

Property #2 (Structural): All levels in a heap must be full except the last level
and all nodes must be filled from left to right strictly.

Max Heap

Max heap data structure is a specialized full binary tree data structure. In a
max heap nodes are arranged based on node value.

Max heap is defined as follows...

Max heap is a specialized full binary tree in which every parent node contains
greater or equal value than its child nodes.

Example
Above tree is satisfying both Ordering property and Structural property
according to the Max Heap data structure.

Operations on Max Heap

The following operations are performed on a Max heap data structure...

1. Finding Maximum
2. Insertion
3. Deletion

Finding Maximum Value Operation in Max Heap

Finding the node which has maximum value in a max heap is very simple. In a
max heap, the root node has the maximum value than all other nodes. So,
directly we can display root node value as the maximum value in max heap.

Insertion Operation in Max Heap

Insertion Operation in max heap is performed as follows...

 Step 1 - Insert the newNode as last leaf from left to right.


 Step 2 - Compare newNode value with its Parent node.
 Step 3 - If newNode value is greater than its parent, then swap both of
them.
 Step 4 - Repeat step 2 and step 3 until newNode value is less than its
parent node (or) newNode reaches to root.

Example
Consider the above max heap. Insert a new node with value 85.

 Step 1 - Insert the newNode with value 85 as last leaf from left to right.
That means newNode is added as a right child of node with value 75.
After adding max heap is as follows...
 Step 2 - Compare newNode value (85) with its Parent node value (75).
That means 85 > 75
 Step 3 - Here newNode value (85) is greater than its parent value (75),
then swap both of them. After swapping, max heap is as follows...

 Step 4 - Now, again compare newNode value (85) with its parent node
value (89).

Here, newNode value (85) is smaller than its parent node value (89).
So, we stop insertion process. Finally, max heap after insertion of a
new node with value 85 is as follows...
Deletion Operation in Max Heap

In a max heap, deleting the last node is very simple as it does not disturb max
heap properties.

Deleting root node from a max heap is little difficult as it disturbs the max
heap properties. We use the following steps to delete the root node from a
max heap...

 Step 1 - Swap the root node with last node in max heap
 Step 2 - Delete last node.
 Step 3 - Now, compare root value with its left child value.
 Step 4 - If root value is smaller than its left child, then compare left
child with its right sibling. Else goto Step 6
 Step 5 - If left child value is larger than its right sibling, then swap
root with left child otherwise swap root with its right child.
 Step 6 - If root value is larger than its left child, then compare root
value with its right child value.
 Step 7 - If root value is smaller than its right child, then swap
root with right child otherwise stop the process.
 Step 8 - Repeat the same until root node fixes at its exact position.
Example
Consider the above max heap. Delete root node (90) from the max heap.

 Step 1 - Swap the root node (90) with last node 75 in max heap. After
swapping max heap is as follows...

 Step 2 - Delete last node. Here the last node is 90. After deleting node
with value 90 from heap, max heap is as follows...
 Step 3 - Compare root node (75) with its left child (89).

Here, root value (75) is smaller than its left child value (89). So,
compare left child (89) with its right sibling (70).

 Step 4 - Here, left child value (89) is larger than its right sibling (70),
So, swap root (75) with left child (89).
 Step 5 - Now, again compare 75 with its left child (36).

Here, node with value 75 is larger than its left child. So, we compare
node 75 with its right child 85.
 Step 6 - Here, node with value 75 is smaller than its right child (85). So, we swap both

of them. After swapping max heap is as follows...

 Step 7 - Now, compare node with value 75 with its left child (15).
Here, node with value 75 is larger than its left child (15) and it does not have right child. So we

stop the process.

Finally, max heap after deleting root node (90) is as follows...


Introduction to Graphs
Graph is a non-linear data structure. It contains a set of points known as nodes (or vertices) and

a set of links known as edges (or Arcs). Here edges are used to connect the vertices. A graph is

defined as follows...

Graph is a collection of vertices and arcs in which vertices are connected with arcs

Graph is a collection of nodes and edges in which nodes are connected with edges

Generally, a graph G is represented as G = ( V , E ), where V is set of vertices and E is set of

edges.

Example

The following is a graph with 5 vertices and 6 edges.

This graph G can be defined as G = ( V , E )

Where V = {A,B,C,D,E} and E = {(A,B),(A,C)(A,D),(B,D),(C,D),(B,E),(E,D)}.

Graph Terminology

We use the following terms in graph data structure...

Vertex

Individual data element of a graph is called as Vertex. Vertex is also known as node. In above

example graph, A, B, C, D & E are known as vertices.


Edge

An edge is a connecting link between two vertices. Edge is also known as Arc. An edge is

represented as (startingVertex, endingVertex). For example, in above graph the link between

vertices A and B is represented as (A,B). In above example graph, there are 7 edges (i.e., (A,B),

(A,C), (A,D), (B,D), (B,E), (C,D), (D,E)).

Edges are three types.

1. Undirected Edge - An undirected egde is a bidirectional edge. If there is undirected

edge between vertices A and B then edge (A , B) is equal to edge (B , A).

2. Directed Edge - A directed egde is a unidirectional edge. If there is directed edge

between vertices A and B then edge (A , B) is not equal to edge (B , A).

3. Weighted Edge - A weighted egde is a edge with value (cost) on it.

Undirected Graph

A graph with only undirected edges is said to be undirected graph.

Directed Graph

A graph with only directed edges is said to be directed graph.

Mixed Graph

A graph with both undirected and directed edges is said to be mixed graph.

End vertices or Endpoints

The two vertices joined by edge are called end vertices (or endpoints) of that edge.

Origin

If a edge is directed, its first endpoint is said to be the origin of it.

Destination
If a edge is directed, its first endpoint is said to be the origin of it and the other endpoint is said to

be the destination of that edge.

Adjacent

If there is an edge between vertices A and B then both A and B are said to be adjacent. In other

words, vertices A and B are said to be adjacent if there is an edge between them.

Incident

Edge is said to be incident on a vertex if the vertex is one of the endpoints of that edge.

Outgoing Edge

A directed edge is said to be outgoing edge on its origin vertex.

Incoming Edge

A directed edge is said to be incoming edge on its destination vertex.

Degree

Total number of edges connected to a vertex is said to be degree of that vertex.

Indegree

Total number of incoming edges connected to a vertex is said to be indegree of that vertex.

Outdegree

Total number of outgoing edges connected to a vertex is said to be outdegree of that vertex.

Parallel edges or Multiple edges

If there are two undirected edges with same end vertices and two directed edges with same

origin and destination, such edges are called parallel edges or multiple edges.

Self-loop

Edge (undirected or directed) is a self-loop if its two endpoints coincide with each other.
Simple Graph

A graph is said to be simple if there are no parallel and self-loop edges.

Path

A path is a sequence of alternate vertices and edges that starts at a vertex and ends at other

vertex such that each edge is incident to its predecessor and successor vertex.

Graph Representations
Graph data structure is represented using following representations...

1. Adjacency Matrix

2. Incidence Matrix

3. Adjacency List

Adjacency Matrix

In this representation, the graph is represented using a matrix of size total number of vertices by

a total number of vertices. That means a graph with 4 vertices is represented using a matrix of

size 4X4. In this matrix, both rows and columns represent vertices. This matrix is filled with either

1 or 0. Here, 1 represents that there is an edge from row vertex to column vertex and 0

represents that there is no edge from row vertex to column vertex.

For example, consider the following undirected graph representation...


Directed graph representation...

Incidence Matrix
In this representation, the graph is represented using a matrix of size total number of vertices by

a total number of edges. That means graph with 4 vertices and 6 edges is represented using a

matrix of size 4X6. In this matrix, rows represent vertices and columns represents edges. This

matrix is filled with 0 or 1 or -1. Here, 0 represents that the row edge is not connected to column

vertex, 1 represents that the row edge is connected as the outgoing edge to column vertex and -

1 represents that the row edge is connected as the incoming edge to column vertex.

For example, consider the following directed graph representation...

Adjacency List

In this representation, every vertex of a graph contains list of its adjacent vertices.

For example, consider the following directed graph representation implemented using linked list...
This representation can also be implemented using an array as follows..
Graph Traversal - DFS
Graph traversal is a technique used for a searching vertex in a graph. The graph traversal is also

used to decide the order of vertices is visited in the search process. A graph traversal finds the

edges to be used in the search process without creating loops. That means using graph traversal

we visit all the vertices of the graph without getting into looping path.

There are two graph traversal techniques and they are as follows...

1. DFS (Depth First Search)

2. BFS (Breadth First Search)

DFS (Depth First Search)

DFS traversal of a graph produces a spanning tree as final result. Spanning Tree is a graph

without loops. We use Stack data structure with maximum size of total number of vertices in the

graph to implement DFS traversal.

We use the following steps to implement DFS traversal...

 Step 1 - Define a Stack of size total number of vertices in the graph.

 Step 2 - Select any vertex as starting point for traversal. Visit that vertex and push it on

to the Stack.

 Step 3 - Visit any one of the non-visited adjacent vertices of a vertex which is at the top

of stack and push it on to the stack.

 Step 4 - Repeat step 3 until there is no new vertex to be visited from the vertex which is

at the top of the stack.

 Step 5 - When there is no new vertex to visit then use back tracking and pop one vertex

from the stack.

 Step 6 - Repeat steps 3, 4 and 5 until stack becomes Empty.


 Step 7 - When stack becomes Empty, then produce final spanning tree by removing

unused edges from the graph

Back tracking is coming back to the vertex from which we reached the current vertex.
Example
Graph Traversal - BFS
Graph traversal is a technique used for searching a vertex in a graph. The graph traversal is also

used to decide the order of vertices is visited in the search process. A graph traversal finds the

edges to be used in the search process without creating loops. That means using graph traversal

we visit all the vertices of the graph without getting into looping path.

There are two graph traversal techniques and they are as follows...

1. DFS (Depth First Search)

2. BFS (Breadth First Search)

BFS (Breadth First Search)

BFS traversal of a graph produces a spanning tree as final result. Spanning Tree is a graph

without loops. We use Queue data structure with maximum size of total number of vertices in

the graph to implement BFS traversal.

We use the following steps to implement BFS traversal...

 Step 1 - Define a Queue of size total number of vertices in the graph.

 Step 2 - Select any vertex as starting point for traversal. Visit that vertex and insert it

into the Queue.

 Step 3 - Visit all the non-visited adjacent vertices of the vertex which is at front of the

Queue and insert them into the Queue.

 Step 4 - When there is no new vertex to be visited from the vertex which is at front of the

Queue then delete that vertex.

 Step 5 - Repeat steps 3 and 4 until queue becomes empty.

 Step 6 - When queue becomes empty, then produce final spanning tree by removing

unused edges from the graph


Example
Linear Search Algorithm
What is Search?

Search is a process of finding a value in a list of values. In other words, searching is the process

of locating given value position in a list of values.

Linear Search Algorithm (Sequential Search Algorithm)

Linear search algorithm finds a given element in a list of elements with O(n) time complexity

where n is total number of elements in the list. This search process starts comparing search

element with the first element in the list. If both are matched then result is element found

otherwise search element is compared with the next element in the list. Repeat the same until

search element is compared with the last element in the list, if that last element also doesn't

match, then the result is "Element not found in the list". That means, the search element is

compared with element by element in the list.

Linear search is implemented using following steps...

 Step 1 - Read the search element from the user.

 Step 2 - Compare the search element with the first element in the list.

 Step 3 - If both are matched, then display "Given element is found!!!" and terminate the

function

 Step 4 - If both are not matched, then compare search element with the next element in

the list.

 Step 5 - Repeat steps 3 and 4 until search element is compared with last element in the

list.

 Step 6 - If last element in the list also doesn't match, then display "Element is not

found!!!" and terminate the function.


Example

Consider the following list of elements and the element to be searched...


Binary Search Algorithm
What is Search?

Search is a process of finding a value in a list of values. In other words, searching is the process

of locating given value position in a list of values.

Binary Search Algorithm

Binary search algorithm finds a given element in a list of elements with O(log n) time complexity

where n is total number of elements in the list. The binary search algorithm can be used with only

a sorted list of elements. That means the binary search is used only with a list of elements that

are already arranged in an order. The binary search can not be used for a list of elements

arranged in random order. This search process starts comparing the search element with the

middle element in the list. If both are matched, then the result is "element found". Otherwise, we

check whether the search element is smaller or larger than the middle element in the list. If the

search element is smaller, then we repeat the same process for the left sublist of the middle

element. If the search element is larger, then we repeat the same process for the right sublist of

the middle element. We repeat this process until we find the search element in the list or until we

left with a sublist of only one element. And if that element also doesn't match with the search

element, then the result is "Element not found in the list".

Binary search is implemented using following steps...

 Step 1 - Read the search element from the user.

 Step 2 - Find the middle element in the sorted list.

 Step 3 - Compare the search element with the middle element in the sorted list.

 Step 4 - If both are matched, then display "Given element is found!!!" and terminate the

function.

 Step 5 - If both are not matched, then check whether the search element is smaller or

larger than the middle element.


 Step 6 - If the search element is smaller than middle element, repeat steps 2, 3, 4 and 5

for the left sublist of the middle element.

 Step 7 - If the search element is larger than middle element, repeat steps 2, 3, 4 and 5

for the right sublist of the middle element.

 Step 8 - Repeat the same process until we find the search element in the list or until

sublist contains only one element.

 Step 9 - If that element also doesn't match with the search element, then display

"Element is not found in the list!!!" and terminate the function.

Example

Consider the following list of elements and the element to be searched...


Binary Search Tree
In a binary tree, every node can have a maximum of two children but there is no need to maintain

the order of nodes basing on their values. In a binary tree, the elements are arranged in the order

they arrive at the tree from top to bottom and left to right.

A binary tree has the following time complexities...

1. Search Operation - O(n)

2. Insertion Operation - O(1)

3. Deletion Operation - O(n)

To enhance the performance of binary tree, we use a special type of binary tree known

as Binary Search Tree. Binary search tree mainly focuses on the search operation in a binary

tree. Binary search tree can be defined as follows...

Binary Search Tree is a binary tree in which every node contains only smaller values in its

left subtree and only larger values in its right subtree.

In a binary search tree, all the nodes in the left subtree of any node contains smaller values and

all the nodes in the right subtree of any node contains larger values as shown in the following

figure...
Example

The following tree is a Binary Search Tree. In this tree, left subtree of every node contains nodes

with smaller values and right subtree of every node contains larger values.
Every binary search tree is a binary tree but every binary tree need not to be binary search

tree.

Operations on a Binary Search Tree

The following operations are performed on a binary search tree...

1. Search
2. Insertion

3. Deletion

Search Operation in BST

In a binary search tree, the search operation is performed with O(log n) time complexity. The

search operation is performed as follows...

 Step 1 - Read the search element from the user.

 Step 2 - Compare the search element with the value of root node in the tree.

 Step 3 - If both are matched, then display "Given node is found!!!" and terminate the

function

 Step 4 - If both are not matched, then check whether search element is smaller or larger

than that node value.

 Step 5 - If search element is smaller, then continue the search process in left subtree.

 Step 6- If search element is larger, then continue the search process in right subtree.

 Step 7 - Repeat the same until we find the exact element or until the search element is

compared with the leaf node

 Step 8 - If we reach to the node having the value equal to the search value then display

"Element is found" and terminate the function.

 Step 9 - If we reach to the leaf node and if it is also not matched with the search element,

then display "Element is not found" and terminate the function.

Insertion Operation in BST

In a binary search tree, the insertion operation is performed with O(log n) time complexity. In

binary search tree, new node is always inserted as a leaf node. The insertion operation is

performed as follows...

 Step 1 - Create a newNode with given value and set its left and right to NULL.

 Step 2 - Check whether tree is Empty.

 Step 3 - If the tree is Empty, then set root to newNode.


 Step 4 - If the tree is Not Empty, then check whether the value of newNode

is smaller or larger than the node (here it is root node).

 Step 5 - If newNode is smaller than or equal to the node then move to its left child. If

newNode is larger than the node then move to its right child.

 Step 6- Repeat the above steps until we reach to the leaf node (i.e., reaches to NULL).

 Step 7 - After reaching the leaf node, insert the newNode as left child if the newNode

is smaller or equal to that leaf node or else insert it as right child.

Deletion Operation in BST

In a binary search tree, the deletion operation is performed with O(log n) time complexity.

Deleting a node from Binary search tree includes following three cases...

 Case 1: Deleting a Leaf node (A node with no children)

 Case 2: Deleting a node with one child

 Case 3: Deleting a node with two children

Case 1: Deleting a leaf node

We use the following steps to delete a leaf node from BST...

 Step 1 - Find the node to be deleted using search operation

 Step 2 - Delete the node using free function (If it is a leaf) and terminate the function.

Case 2: Deleting a node with one child

We use the following steps to delete a node with one child from BST...

 Step 1 - Find the node to be deleted using search operation

 Step 2 - If it has only one child then create a link between its parent node and child node.

 Step 3 - Delete the node using free function and terminate the function.

Case 3: Deleting a node with two children

We use the following steps to delete a node with two children from BST...
 Step 1 - Find the node to be deleted using search operation

 Step 2 - If it has two children, then find the largest node in its left subtree (OR)

the smallest node in its right subtree.

 Step 3 - Swap both deleting node and node which is found in the above step.

 Step 4 - Then check whether deleting node came to case 1 or case 2 or else goto step 2

 Step 5 - If it comes to case 1, then delete using case 1 logic.

 Step 6- If it comes to case 2, then delete using case 2 logic.

 Step 7 - Repeat the same process until the node is deleted from the tree.

Example

Construct a Binary Search Tree by inserting the following sequence of numbers...

10,12,5,4,20,8,7,15 and 13

Above elements are inserted into a Binary Search Tree as follows...


AVL Tree Datastructure
AVL tree is a height-balanced binary search tree. That means, an AVL tree is also a binary

search tree but it is a balanced tree. A binary tree is said to be balanced if, the difference

between the heights of left and right subtrees of every node in the tree is either -1, 0 or +1. In

other words, a binary tree is said to be balanced if the height of left and right children of every

node differ by either -1, 0 or +1. In an AVL tree, every node maintains an extra information

known as balance factor. The AVL tree was introduced in the year 1962 by G.M. Adelson-

Velsky and E.M. Landis.

An AVL tree is defined as follows...

An AVL tree is a balanced binary search tree. In an AVL tree, balance factor of every node

is either -1, 0 or +1.

Balance factor of a node is the difference between the heights of the left and right subtrees of

that node. The balance factor of a node is calculated either height of left subtree - height of

right subtree (OR) height of right subtree - height of left subtree. In the following

explanation, we calculate as follows...

Balance factor = heightOfLeftSubtree - heightOfRightSubtree


Example of AVL Tree

The above tree is a binary search tree and every node is satisfying balance factor condition. So

this tree is said to be an AVL tree.

Every AVL Tree is a binary search tree but every Binary Search Tree need not be AVL tree.

AVL Tree Rotations

In AVL tree, after performing operations like insertion and deletion we need to check the balance

factor of every node in the tree. If every node satisfies the balance factor condition then we
conclude the operation otherwise we must make it balanced. Whenever the tree becomes

imbalanced due to any operation we use rotation operations to make the tree balanced.

Rotation operations are used to make the tree balanced.

Rotation is the process of moving nodes either to left or to right to make the tree

balanced.

There are four rotations and they are classified into two types.

Single Left Rotation (LL Rotation)

In LL Rotation, every node moves one position to left from the current position. To understand LL

Rotation, let us consider the following insertion operation in AVL Tree...


Single Right Rotation (RR Rotation)

In RR Rotation, every node moves one position to right from the current position. To understand

RR Rotation, let us consider the following insertion operation in AVL Tree...


Left Right Rotation (LR Rotation)

The LR Rotation is a sequence of single left rotation followed by a single right rotation. In LR

Rotation, at first, every node moves one position to the left and one position to right from the

current position. To understand LR Rotation, let us consider the following insertion operation in

AVL Tree...

Right Left Rotation (RL Rotation)

The RL Rotation is sequence of single right rotation followed by single left rotation. In RL

Rotation, at first every node moves one position to right and one position to left from the current

position. To understand RL Rotation, let us consider the following insertion operation in AVL

Tree...
Operations on an AVL Tree

The following operations are performed on AVL tree...

1. Search

2. Insertion

3. Deletion

Search Operation in AVL Tree

In an AVL tree, the search operation is performed with O(log n) time complexity. The search

operation in the AVL tree is similar to the search operation in a Binary search tree. We use the

following steps to search an element in AVL tree...

 Step 1 - Read the search element from the user.

 Step 2 - Compare the search element with the value of root node in the tree.

 Step 3 - If both are matched, then display "Given node is found!!!" and terminate the

function
 Step 4 - If both are not matched, then check whether search element is smaller or larger

than that node value.

 Step 5 - If search element is smaller, then continue the search process in left subtree.

 Step 6 - If search element is larger, then continue the search process in right subtree.

 Step 7 - Repeat the same until we find the exact element or until the search element is

compared with the leaf node.

 Step 8 - If we reach to the node having the value equal to the search value, then display

"Element is found" and terminate the function.

 Step 9 - If we reach to the leaf node and if it is also not matched with the search element,

then display "Element is not found" and terminate the function.

Insertion Operation in AVL Tree

In an AVL tree, the insertion operation is performed with O(log n) time complexity. In AVL Tree,

a new node is always inserted as a leaf node. The insertion operation is performed as follows...

 Step 1 - Insert the new element into the tree using Binary Search Tree insertion logic.

 Step 2 - After insertion, check the Balance Factor of every node.

 Step 3 - If the Balance Factor of every node is 0 or 1 or -1 then go for next operation.

 Step 4 - If the Balance Factor of any node is other than 0 or 1 or -1 then that tree is said

to be imbalanced. In this case, perform suitable Rotation to make it balanced and go for

next operation.

Example: Construct an AVL Tree by inserting numbers from 1 to


8.
Deletion Operation in AVL Tree

The deletion operation in AVL Tree is similar to deletion operation in BST. But after every

deletion operation, we need to check with the Balance Factor condition. If the tree is balanced

after deletion go for next operation otherwise perform suitable rotation to make the tree

Balanced.
Insertion Sort Algorithm

Sorting is the process of arranging a list of elements in a particular order (Ascending or

Descending).

Insertion sort algorithm arranges a list of elements in a particular order. In insertion sort

algorithm, every iteration moves an element from unsorted portion to sorted portion until all the

elements are sorted in the list.

Step by Step Process

The insertion sort algorithm is performed using the following steps...

 Step 1 - Assume that first element in the list is in sorted portion and all the remaining

elements are in unsorted portion.

 Step 2: Take first element from the unsorted portion and insert that element into the

sorted portion in the order specified.

 Step 3: Repeat the above process until all the elements from the unsorted portion are

moved into the sorted portion.

Following is the sample code for insertion sort...

Insertion Sort Logic


//Insertion sort logic
for i = 1 to size-1 {
temp = list[i];
j = i-1;
while ((temp < list[j]) && (j > 0)) {
list[j] = list[j-1];
j = j - 1;
}
list[j] = temp;
}
Example
Complexity of the Insertion Sort Algorithm

To sort an unsorted list with 'n' number of elements, we need to make (1+2+3+......+n-1) = (n (n-

1))/2 number of comparisions in the worst case. If the list is already sorted then it

requires 'n' number of comparisions.


WorstCase : O(n2)
BestCase : Ω(n)
Average Case : Θ(n2)

Selection Sort Algorithm


Selection Sort algorithm is used to arrange a list of elements in a particular order (Ascending or

Descending). In selection sort, the first element in the list is selected and it is compared

repeatedly with all the remaining elements in the list. If any element is smaller than the selected

element (for Ascending order), then both are swapped so that first position is filled with the

smallest element in the sorted order. Next, we select the element at a second position in the list

and it is compared with all the remaining elements in the list. If any element is smaller than the

selected element, then both are swapped. This procedure is repeated until the entire list is

sorted.

Step by Step Process

The selection sort algorithm is performed using the following steps...

 Step 1 - Select the first element of the list (i.e., Element at first position in the list).

 Step 2: Compare the selected element with all the other elements in the list.

 Step 3: In every comparision, if any element is found smaller than the selected element

(for Ascending order), then both are swapped.

 Step 4: Repeat the same procedure with element in the next position in the list till the

entire list is sorted.

Following is the sample code for selection sort...

Selection Sort Logic


//Selection sort logic

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


for(j=i+1; j<size; j++){
if(list[i] > list[j])
{
temp=list[i];
list[i]=list[j];
list[j]=temp;
}
}
}

Example
Complexity of the Selection Sort Algorithm

To sort an unsorted list with 'n' number of elements, we need to make ((n-1)+(n-2)+(n-3)+......+1)

= (n (n-1))/2 number of comparisions in the worst case. If the list is already sorted then it

requires 'n' number of comparisions.


Worst Case : O(n2)
Best Case : Ω(n2)
Average Case : Θ(n2)

Quick Sort Algorithm


Quick sort is a fast sorting algorithm used to sort a list of elements. Quick sort algorithm is

invented by C. A. R. Hoare.

The quick sort algorithm attempts to separate the list of elements into two parts and then sort

each part recursively. That means it use divide and conquer strategy. In quick sort, the partition

of the list is performed based on the element called pivot. Here pivot element is one of the

elements in the list.

The list is divided into two partitions such that "all elements to the left of pivot are smaller

than the pivot and all elements to the right of pivot are greater than or equal to the pivot".

Step by Step Process

In Quick sort algorithm, partitioning of the list is performed using following steps...

 Step 1 - Consider the first element of the list as pivot (i.e., Element at first position in the

list).

 Step 2 - Define two variables i and j. Set i and j to first and last elements of the list

respectively.

 Step 3 - Increment i until list[i] > pivot then stop.

 Step 4 - Decrement j until list[j] < pivot then stop.

 Step 5 - If i < j then exchange list[i] and list[j].

 Step 6 - Repeat steps 3,4 & 5 until i > j.


 Step 7 - Exchange the pivot element with list[j] element.

Following is the sample code for Quick sort...

Quick Sort Logic


//Quick Sort Logic
void quickSort(int list[10],int first,int last){
int pivot,i,j,temp;

if(first < last){


pivot = first;
i = first;
j = last;

while(i < j){


while(list[i] <= list[pivot] && i < last)
i++;
while(list[j] && list[pivot])
j--;
if(i < j){
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}

temp = list[pivot];
list[pivot] = list[j];
list[j] = temp;
quickSort(list,first,j-1);
quickSort(list,j+1,last);
}
}

Example
Complexity of the Quick Sort Algorithm

To sort an unsorted list with 'n' number of elements, we need to make ((n-1)+(n-2)+(n-3)+......+1)

= (n (n-1))/2 number of comparisions in the worst case. If the list is already sorted, then it

requires 'n' number of comparisions.


Worst Case : O(n2)
Best Case : O (n log n)
Average Case : O (n log n)

Heap Sort Algorithm


Heap sort is one of the sorting algorithms used to arrange a list of elements in order. Heapsort

algorithm uses one of the tree concepts called Heap Tree. In this sorting algorithm, we use Max

Heap to arrange list of elements in Descending order and Min Heap to arrange list elements in

Ascending order.

Step by Step Process

The Heap sort algorithm to arrange a list of elements in ascending order is performed using

following steps...

 Step 1 - Construct a Binary Tree with given list of Elements.

 Step 2 - Transform the Binary Tree into Min Heap.

 Step 3 - Delete the root element from Min Heap using Heapify method.

 Step 4 - Put the deleted element into the Sorted list.

 Step 5 - Repeat the same until Min Heap becomes empty.

 Step 6 - Display the sorted list.

Example
Complexity of the Heap Sort Algorithm

To sort an unsorted list with 'n' number of elements, following are the complexities...

Worst Case : O(n log n)


Best Case : O(n log n)
Average Case : O(n log n)

You might also like