Download Prim`s Algorithm

Document related concepts

Array data structure wikipedia , lookup

Lattice model (finance) wikipedia , lookup

Red–black tree wikipedia , lookup

Quadtree wikipedia , lookup

Linked list wikipedia , lookup

Interval tree wikipedia , lookup

B-tree wikipedia , lookup

Binary tree wikipedia , lookup

Binary search tree wikipedia , lookup

Transcript
UNIT – I
Data Structure: Data may be organized in the logical and mathematical model of a particular organization of
data is called a “Data Structure”. The choice of a particular data model depends on two
considerations: 1. It must be rich enough in structure to mirror the actual relationships of the data in the real
world.
2. The structure should be simple enough that one can effectively process the data when
necessary.
In other words data structure is a collection of data elements whose organization is
characterized by assessing operations that are used to store and retrieve the individual data elements.
Abstract data type: An abstract data type can be defined as a data type whose properties are specified
independently of any particular implementation. The data structures are classified in the following
two categories:  Linear data structure
 Nonlinear data structure
1. Linear data structure: In the linear data structures processing of data items are possible in linear fashion i.e.
data can be processed sequentially. Linear data structures include the following types of data
structures:  Array
 Stack
 Queues
 Linked List
1.) Arrays: The simplest type of data structure is a linear or one-dimensional array. By a linear
array, we mean a list of finite number ‘n’ of similar data elements referenced respectively
by a set of ‘n’ consecutive numbers, usually 1,2,3,4,……..,n. if we choose the name A for
the array, then the elements of A are denoted by subscript notation –
A1, A2, A3,………..An
Or by parenthesis notation –
A(1), A(2), A(3),……….A(n)
Or by bracket notation –
A[1], A[2], A[3],……….A[n]
The number k in A[k] is called a subscript and A[k] is called a subscripted variable or
array variable. Linear arrays are called one-dimensional arrays because each element in
such an array is referenced by one subscript. A two-dimensional array is a collection of
similar data elements where each element is referenced by two subscripts. Such arrays are
called matrices in mathematics and tables in business applications.
2.) Stack: A stack also known as Last-in-First-out system that is a linear list in which insertions
and deletions can take place only at one end, called the top of stack. Stack is just like a
container of CDs in which CDs are put one on another.
3.) Queue: A queue also called a First-in-First-out (FIFO) system that is a linear list in which
deletions can take place only at one end of the list called the front of the list and insertions
can take place only at other end of the list called the rear of the list.
4.) Linked List: A linked list is a linear collection of data elements called nodes, where the linear
order is given by means pointers. That is, each node is divided into two parts – the first
Page 1
part contains the information of the element and the second part called the link field or
next pointer field contains the address of the next node in the list.
2. Non-Linear data structure: A data structure in which insertion and deletion is not possible in a linear fashion is
called data structure. Non-Linear data structures include the following types of data
structures:  Tree
 Graph
1.) Tree: Data are arranged in hierarchical manner between various elements. The data
structure which reflects this relationship is called a rooted tree graph or simply a tree.
2.) Graph: Data sometimes contain a relationship between pairs of elements which is not
necessarily hierarchical in nature. The data structure which reflects this type of
relationship is called a graph.
Data structure operations: The data appearing in our data structures are processed by certain operations. The following
operations are: 1. Traversing: Accessing each record exactly once so that certain item in the record may be
processed like display it, compare with another value etc.
2. Searching: Finding the location of the record with a given key value or finding the locations of
all records which satisfy one or more conditions.
3. Insertion: This operation adds a new record to the structure at the given location or any other
value that already exists.
4. Deletion: This operation can remove a record from the structure by giving the location or value.
5. Sorting: This operation rearranges the records in some logical order that is either ascending or
descending order.
6. Merging: This operation can merge the two different data structures or records of files into a
single data structure or file.
7. Update: Modifying the values of existing record by searching the record and manipulate them.
Arrays: -
An array is a derived data type which holds the set of values of the similar data type.
An array is a collection of values or an array is a collection of similar type of variables. An
array provides a convenient structure for representing data; it is classified as one of the data
structures in C. An array is a sequenced collection of related data items that share a common
name. The array occupies the contiguous memory block to store large volume of data. Array
based on static memory allocation concept i.e. an array is a fixed size collection of elements
that cannot vary at run time.



There are three types of array: One-dimensional array
Two-dimensional array
Multi-dimensional array
Page 2
One-dimensional array: A list of items can be given one variable name using only one subscript and such a
variable is called a single-subscripted variable or a one-dimensional array. The starting
element of the array is 0th position and last element is the size-1 position. The values are
stored in array in contiguous order. An array is based on static memory location.
Declaration of One-Dimensional array: Like any other variable, arrays must be declared before they are used. The general
form of array declaration is: Syntax -
datatype variable-name[size];
The datatype specifies the type of element that will be contained in the array and the
size indicates the maximum number of elements that can be stored in the array variable.
e.g. int x[10];
float y[20];
Memory Representation of One-Dimensional array: Array allocates a contiguous block of memory space that is starts from 0th index.
e.g. - int x[10];
0
1
2
3
4
5
6
7
8
9
Initialization of One-Dimensional array: After an array is declared, its elements must be initialized; otherwise they will contain
garbage value. An array can be initialized at either of the following stages:  At compile time
 At run time
1. Compile time initialization: - We can initialize the elements of array as the ordinary
variables when they are declared.
Syntax datatype variable-name[size] = { list of values };
The values are separated by commas.
e.g. int a[10] = {34, 65, 12, 23, 43, 68, 52, 81, 33, 10};
If we don’t specify all values as their size then the remaining elements are initialized
to zero.
e.g. int a[10] = {34, 65, 12, 43, 10};
The size may be omitted. In such cases, compiler allocates enough space for all
initialized elements.
e.g. int a[ ] = {34, 65, 12, 23, 43, 68, 52, 81, 33, 10};
Page 3
2. Run time initialization: - An array can be explicitly initialized at run time.
e.g. int a[10];
a[0] = 34;
a[1] = 65;
a[2] = 12;
a[3] = 23
a[4] = 52;
Accessing elements of One-Dimensional Array: The array can be accessed by individual elements specified by element number as a
constant or variable.
Syntax -
variable[element no]
e.g. -
int a[10];
a[0] = 34;
a[1] = 65;
scanf(“%d”,&a[0]);
scanf(“%d”,&a[1]);
printf(“%d %d”,a[0], a[1]);
for(i = 0; i < 10; i++)
printf(“\n %d”, a[i]);
Operations on One Dimensional Array:  Traversing
 Insertion
 Deletion
 Searching
 Find Maximum and Minimum
 Sorting
Traversing One Dimensional Array: Traverse means access each element from start to end of one dimensional array.
Algorithm – Traverse(Arr, n)
Description – Arr is an array of n elements and n is a natural number that represents the upper
bound of array.
Begin
For i = 0 TO n-1 Step 1
Display Arr[i]
[End of For statement]
End
Page 4
Example – Write a program to calculate sum and average of an integer array of 10 numbers.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[10], i, sum = 0;
float avg;
clrscr( );
printf(“Enter the numbers - ”);
for(i = 0; i < 10; i++)
scanf(“%d”, &a[i]);
for(i = 0; i < 10; i++)
{
printf(“\n %d”, a[i]);
sum = sum + a[i];
}
avg = (float) sum/10;
printf(“\n Sum is = %d”, sum);
printf(“\n Average is = %f”, avg);
getch( );
}
Insertion in One Dimensional Array: The One Dimensional array is a contiguous memory block and values are stored in
sequence. If we want to insert a new element at the given position then first traverse the all
right elements after the given position and then assign a new value at the given position.
Algorithm – Insert(Arr, n, Pos, val)
Description – Arr is an array of n elements and n is a natural number that represents the upper
bound of array. Pos is the position where we want to insert and the val is new value that is to
inserted.
Begin
For i = n-1 TO Pos-1 Step -1
Arr[i+1] = Arr[i]
[End of For statement]
Arr[Pos-1] = val
End
Example – Write a program to insert a new element in an array at given position.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[20], i, n, pos, val;
void insert(int [], int, int, int);
Page 5
clrscr( );
printf(“How many numbers entered in an array - ”);
scanf(“%d”, &n);
printf(“Enter the numbers - ”);
for(i = 0; i < n; i++)
scanf(“%d”, &a[i]);
printf(“\n Array Before Insertion…….”);
for(i = 0; i < n; i++)
printf(“\n %d”, a[i]);
printf(“Enter the position where u want to insert a value - ”);
scanf(“%d”, &pos);
printf(“Enter the new value - ”);
scanf(“%d”, &val);
insert(a, n, pos, val);
n++;
printf(“\n Array After Insertion…….”);
for(i = 0; i < n; i++)
printf(“\n %d”, a[i]);
getch( );
}
void insert(int arr[], int n, int pos, int val)
{
int i;
for(i = n-1; i >= pos-1; i--)
{
arr[i+1] = arr[i];
}
arr[pos-1] = val;
}
Deletion from One Dimensional Array: Deleting an element from the end of an array is simple but deleting an element from
some other position is difficult and requires moving all the elements up-word to fill-up the
gap into the array.
Algorithm – Delete(A, n, Pos)
Begin
For i = Pos-1 TO n-1 Step 1
A[i] = A[i+1]
[End of For statement]
n=n–1
End
Page 6
Example – Write a program to delete an element in an array from given position.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[20], i, n, pos;
void del(int [], int, int);
clrscr( );
printf(“How many numbers entered in an array - ”);
scanf(“%d”, &n);
printf(“Enter the numbers - ”);
for(i = 0; i < n; i++)
scanf(“%d”, &a[i]);
printf(“\n Array Before Deletion…….”);
for(i = 0; i < n; i++)
printf(“\n %d”, a[i]);
printf(“Enter the position from where u want to delete a value - ”);
scanf(“%d”, &pos);
del(a, n, pos);
n--;
printf(“\n Array After Deletion…….”);
for(i = 0; i < n; i++)
printf(“\n %d”, a[i]);
getch( );
}
void del(int arr[], int n, int pos)
{
int i;
for(i = pos-1; i < n; i++)
{
arr[i] = arr[i+1];
}
}
Searching elements from One Dimensional Array: Searching refers to an operation of finding the location of the searching data in an
array and output some message if data does not exist in the array. The search is said to be
successful if data appears in the array else it is called unsuccessful.
There are two methods of searching an element in an array:  Linear Search
 Binary Search
Page 7
1. Linear Search: This is the simplest technique to find out an element in an unsorted list. The
element can be start finding from first element to last element. If the element
is finding on the particular position, then process that position and if it is not
found then display a message.
Algorithm – LinearSearch(A, n, s)
Begin
For i = 0 TO n-1 Step 1
If s = A[i] Then
Return i
[End of if statement]
[End of For statement]
Return -1
End
Example – Write a program to search an element in an array using linear search method.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[20], i, n, s, flag;
int linearsearch(int [], int, int);
clrscr( );
printf(“How many numbers entered in an array - ”);
scanf(“%d”, &n);
printf(“Enter the numbers - ”);
for(i = 0; i < n; i++)
scanf(“%d”, &a[i]);
printf(“Enter the value to be searched - ”);
scanf(“%d”, &s);
flag = linearsearch(a, n, s);
if(flag = = -1)
printf(“Value not found”);
else
printf(“Value found on position = %d”, flag+1);
getch( );
}
int linearsearch(int arr[], int n, int s)
{
int i;
for(i = 0; i < n; i++)
{
if(s = = arr[i])
return i;
Page 8
}
return -1;
}
2. Binary Search: In this searching method, first we required the array element is in ascending
order then we can obtain the element. We define positions low on 0 and high
on n-1 element and then determine the middle position and compare the
searching number from middle value. If the value matches then display their
position but if not then either the first or second half of the array can be
selected for next comparison. This process continues until a match is found or
there are no values left.
Algorithm – BinarySearch(A, n, s)
Begin
[Initialize] low = 0, high = n-1
While low<=high do
Mid = (low + high) / 2
If s = A[mid] Then
Return mid
Else if s < A[mid] Then
high = mid – 1
Else
low = mid + 1
[End of if statement]
[End of while statement]
Return -1
End
Example – Write a program to search an element in an array using binary search method.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[20], i, j, n, s, flag, t;
int binarysearch(int [], int, int);
clrscr( );
printf(“How many numbers entered in an array - ”);
scanf(“%d”, &n);
for(i = 0; i < n; i++)
{
printf(“Enter the number - ”);
scanf(“%d”, &a[i]);
}
Page 9
// Process for sorting
for(i = 0; i < n; i++)
{
for(j = 0; j < n-i-1; j++)
{
if(a[j] > a[j+1])
{
t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
}
printf(“Enter the value to be searched - ”);
scanf(“%d”, &s);
flag = binarysearch(a, n, s);
if(flag = = -1)
printf(“Value not found”);
else
printf(“Value found on position = %d”, flag+1);
getch( );
}
int binarysearch(int arr[], int n, int s)
{
int low, high, mid;
low = 0;
high = n-1;
while(low<=high)
{
mid = (low + high)/2;
if(s = = arr[mid])
return mid;
else if(s < arr[mid])
high = mid - 1;
else
low = mid + 1;
}
return -1;
}
Find Maximum/Minimum from One Dimensional array: To find the maximum/minimum value from one dimensional array, we consider the
0th element as maximum/minimum number and then compare each element of array from 1 to
n-1 with maximum/minimum value. If any other number is maximum/minimum number then
Page 10
change the maximum/minimum value. This process continues till the last element. The
maximum/minimum value will be produces as output.
Algorithm – Maximum(Arr, n)
Description – Arr is an array of n elements and n is a natural number that represents the upper
bound of array.
Begin
max = Arr[0]
For i = 1 TO n-1 Step 1
If Arr[i] > max Then
max = Arr[i]
[End of if statement]
[End of For statement]
Return max
End
Example – Write a program to search the maximum from an array.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[20], i, n, max;
int maximum(int [], int);
clrscr( );
printf(“How many numbers entered in an array - ”);
scanf(“%d”, &n);
printf(“Enter the numbers - ”);
for(i = 0; i < n; i++)
scanf(“%d”, &a[i]);
max = maximum(a, n);
printf(“Maximum Value is = %d”, max);
getch( );
}
int maximum(int arr[], int n)
{
int max, i;
max = arr[0];
for(i = 1; i < n; i++)
{
if(arr[i] > max)
max = arr[i];
}
return max;
}
Page 11
Algorithm – Minimum(Arr, n)
Description – Arr is an array of n elements and n is a natural number that represents the upper
bound of array.
Begin
min = Arr[0]
For i = 1 TO n-1 Step 1
If Arr[i] < min Then
min = Arr[i]
[End of if statement]
[End of For statement]
Return min
End
Example – Write a program to search the minimum from an array.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[20], i, n, min;
int maximum(int [], int);
clrscr( );
printf(“How many numbers entered in an array - ”);
scanf(“%d”, &n);
printf(“Enter the numbers - ”);
for(i = 0; i < n; i++)
scanf(“%d”, &a[i]);
min = maximum(a, n);
printf(“Minimum Value is = %d”, min);
getch( );
}
int minimum(int arr[], int n)
{
int min, i;
min = arr[0];
for(i = 1; i < n; i++)
{
if(arr[i] > min)
min = arr[i];
}
return min;
}
Page 12
Sorting an array: Sorting is the process of arranging elements in the list according to their values in
ascending and descending order. A sorted list is called an ordered list. Many sorting
techniques are available.
1. Bubble Sort: It is very simple sorting method. However, this sorting technique is not
efficient in comparison to other sorting technique. In bubble sort method, each
element is compared with next element. If the current element is greater than second
then interchange their values. This process continues when the list is not completely
sorted.
Algorithm – BubbleSort(Arr, n)
Description – Arr is an array of n elements and n is a natural number that represents the upper
bound of array.
Begin
For i = 0 TO n-1 Step 1
For j = 0 TO n-i-1 Step 1
If Arr[ j] > Arr[ j+1] Then
t = Arr[ j]
Arr[ j] = Arr[ j+1]
Arr[ j+1] = t
[End of if statement]
[End of For statement]
[End of For statement]
End
Example – Write a program to sort an array using bubble sort.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[20], i, n;
void bubblesort(int [], int);
clrscr( );
printf(“How many numbers entered in an array - ”);
scanf(“%d”, &n);
printf(“Enter the numbers - ”);
for(i = 0; i < n; i++)
scanf(“%d”, &a[i]);
bubblesort(a, n);
for(i = 0; i < n; i++)
printf(“\n %d”, a[i]);
getch( );
}
Page 13
void bubblesort(int arr[], int n)
{
int i, j, t;
for(i = 0; i < n; i++)
{
for( j = 0; j < n; j++)
{
if(arr[ j] > arr[ j+1])
{
t = arr[ j];
arr[ j] = arr[ j+1];
arr[ j+1] = t;
}
}
}
}
Two-Dimensional Arrays: In Two-dimensional arrays, two subscripts are used to reference an element of the
array one for row elements and second for column elements. The two dimensional arrays is
also known as matrix.
Declaration of Two-Dimensional array: Like one dimensional arrays, two dimensional must be declared before they are used.
The general form of declaration is: Syntax -
datatype variable-name[row-size][column-size];
The datatype specifies the type of element that will be contained in the array and the
row-size & column-size indicates the maximum number of rows and columns that can be
stored in the array variable.
e.g. int x[3][3];
float y[5][4];
Initialization of Two-Dimensional array: Like the one-dimensional arrays, two-dimensional array may be initialized by
following their declaration with a list of initial values enclosed in braces.
Syntax datatype variable-name[row-size][col-size] = { list of values };
The values are separated by commas.
e.g. int a[3][3] = {34, 65, 12, 23, 43, 68, 52, 81, 33};
If we don’t specify all values as their size then the remaining elements are initialized
to zero.
e.g. int a[3][3] = {34, 65, 12, 43, 10};
Page 14
The row size may be omitted. In such cases, compiler allocates enough space for all
initialized elements.
e.g. int a[ ][3] = {34, 65, 12, 23, 43, 68, 52, 81, 33};
The initialization is done row by row.
e.g. int a[ ][3] = {
{34, 65, 12},
{23, 43, 68},
{52, 81, 33}};
Accessing elements of Two-Dimensional Array: The array can be accessed by individual elements specified by row element and
column element number as a constant or variable.
Syntax variable[row element no][column element no]
e.g. -
int a[3][3];
a[0][0] = 34;
a[1][0] = 65;
scanf(“%d”, &a[0][0]);
scanf(“%d”, &a[0][1]);
printf(“%d %d”, a[0][0], a[0][1]);
Operations on Two Dimensional Array:  Traversing
 Transpose of a Matrix
 Addition of Matrices
 Subtraction of Matrices
 Multiplication of Matrices
Traversing Two Dimensional Array: Traverse means access each element from start to end of two dimensional arrays.
Traversing of two dimensional arrays can be classified into two categories:  Column major order
 Row major order.
Algorithm – Traverse(Arr, n)
Description – Arr is a two-dimensional array of n*n elements.
Begin
For i = 0 TO n-1 Step 1
For j = 0 TO n-1 Step 1
Display Arr[ i ][ j ]
[End of For statement]
[End of For statement]
End
Page 15
Example – Write a program to input and print a matrix.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[3][3], i, j;
clrscr( );
printf(“Enter the numbers - ”);
for(i = 0; i < 3; i++)
for( j = 0; j < 3; j++)
scanf(“%d”, &a[ i ][ j ]);
for(i = 0; i < 3; i++)
{
for( j = 0; j < 3; j++)
{
printf(“%4d”, a[ i ][ j ]);
}
printf(“\n”);
}
getch( );
}
Transpose of a Matrix: It is obtained by interchanging the rows with corresponding columns of a given
matrix. The transpose of a matrix A is generally denoted by AT. if matrix A is an m x n then
after transposing it we will get an n x m matrix AT.
Algorithm – Tranpose(A, n)
Description – Arr is a two-dimensional array of n*n elements.
Begin
For i = 0 TO n-1 Step 1
For j = 0 TO n-1 Step 1
Display A[ j ][ i ]
[End of For statement]
[End of For statement]
End
Example – Write a program to transpose the matrix.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[3][3], i, j;
clrscr( );
Page 16
printf(“Enter the numbers - ”);
for(i = 0; i < 3; i++)
for( j = 0; j < 3; j++)
scanf(“%d”, &a[ i ][ j ]);
printf(“Transpose matrix…….\n”);
for(i = 0; i < 3; i++)
{
for( j = 0; j < 3; j++)
{
printf(“%4d”, a[ j ][ i ]);
}
printf(“\n”);
}
getch( );
}
Addition of Matrices: Let A and B are two matrices of the same order. Then their sum, A+B is defined as a
matrix, each of which is summation of corresponding elements of A and B.
Algorithm – Addition of Two Matrices
Begin
For i = 0 TO n-1 Step 1
For j = 0 TO n-1 Step 1
C[ i ][ j ] = A[ i ][ j ] + B[ i ][ j ]
[End of For statement]
[End of For statement]
End
Example – Write a program to addition of two matrices.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[3][3], b[3][3], c[3][3], i, j;
clrscr( );
printf(“Enter the numbers in first matrix……….\n”);
for(i = 0; i < 3; i++)
for( j = 0; j < 3; j++)
scanf(“%d”, &a[ i ][ j ]);
printf(“Enter the numbers in second matrix……….\n”);
for(i = 0; i < 3; i++)
for( j = 0; j < 3; j++)
scanf(“%d”, &b[ i ][ j ]);
Page 17
printf(“Addition of two matrices…….\n”);
for(i = 0; i < 3; i++)
{
for( j = 0; j < 3; j++)
{
c[ i ][ j ] = a[ i ][ j ] + b[ i ][ j ];
printf(“%4d”, c[ i ][ j ]);
}
printf(“\n”);
}
getch( );
}
Subtraction of Matrices: Let A and B are two matrices of the same order. Then their subtraction, A-B is
defined as a matrix, each of which is subtraction of corresponding elements of A and B.
Algorithm – Subtraction of Two Matrices
Begin
For i = 0 TO n-1 Step 1
For j = 0 TO n-1 Step 1
C[ i ][ j ] = A[ i ][ j ] - B[ i ][ j ]
[End of For statement]
[End of For statement]
End
Multiplication of Matrices: Let A and B are two matrices of the same order. Then their multiplication, A*B is
defined as a matrix, each of which is multiplication of each row from A matrix to each
column of B matrix.
Algorithm – Multiplication of Two Matrices
Begin
For i = 0 TO n-1 Step 1
For j = 0 TO n-1 Step 1
C[ i ][ j ] = 0
For k = 0 TO n-1 Step 1
C[ i ][ j ] = C[ i ][ j ] + A[ i ][ k ] * B[ k ][ j ]
[End of For statement]
[End of For statement]
[End of For statement]
End
Page 18
Example – Write a program to multiplication of two matrices.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[3][3], b[3][3], c[3][3], i, j, k;
clrscr( );
printf(“Enter the numbers in first matrix……….\n”);
for(i = 0; i < 3; i++)
for( j = 0; j < 3; j++)
scanf(“%d”, &a[ i ][ j ]);
printf(“Enter the numbers in second matrix……….\n”);
for(i = 0; i < 3; i++)
for( j = 0; j < 3; j++)
scanf(“%d”, &b[ i ][ j ]);
printf(“Multiplication of two matrices…….\n”);
for(i = 0; i < 3; i++)
{
for( j = 0; j < 3; j++)
{
c[ i ][ j ] = 0;
for( k = 0; k < 3; k++)
{
c[ i ][ j ] = c[ i ][ j ] + a[ i ][ k ] * b[ k ][ j ];
}
printf(“%4d”, c[ i ][ j ]);
}
printf(“\n”);
}
getch( );
}
Sparse Matrix: Matrices with a relatively high proportion of zero entries are called sparse matrices.
Two general types of n-square sparse matrices: 1. Triangular matrix
2. Tri-diagonal matrix
If all entries above the main diagonal are zero or equivalently where non-zero entries
can only occur on or below the main diagonal is called a lower triangular matrix.
If all entries below the main diagonal are zero or equivalently where non-zero entries
can only occur on or above the main diagonal is called upper triangular matrix.
If non-zero entries can only occur on the diagonal or on elements, immediately above
or below the diagonal is called a tri-diagonal matrix.
Page 19
Example 1
6
11
16
21
0
7
12
17
22
0
0
13
18
23
0
0
0
19
24
0
0
0
0
25
1
0
0
0
0
2
7
0
0
0
3
8
13
0
0
4
9
14
19
0
5
10
15
20
25
1
6
0
0
0
2
7
12
0
0
0
8
13
18
0
0
0
14
19
24
0
0
0
20
25
Lower Triangular
Matrix
Example -
Upper Triangular
Matrix
Example -
Tri-Diagonal
Matrix
Examples: - Develop a program to print the lower triangular and upper triangular matrix.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[3][3], i, j, ch;
clrscr( );
printf(“Enter the numbers in matrix - ”);
for(i = 0; i < 3; i++)
for( j = 0; j < 3; j++)
scanf("%d", &a[ i ][ j ]);
printf("\n 1. Original Matrix");
printf("\n 2. Lower Triangular Matrix");
printf("\n 3. Upper Triangular Matrix");
printf("\n Enter the choice - ");
scanf("%d", &ch);
switch(ch)
{
case 1:
printf("Original matrix.....\n");
for(i = 0; i < 3; i++)
{
for( j = 0; j < 3; j++)
{
printf("%4d", a[ i ][ j ]);
}
Page 20
printf("\n");
}
break;
case 2:
printf("Lower Triangular Matrix....\n");
for(i = 0; i < 3; i++)
{
for( j = 0; j < 3; j++)
{
if( i >= j )
printf("%4d", a[ i ][ j ]);
else
printf("%4d", 0);
}
printf("\n");
}
break;
case 3:
printf("Upper Triangular Matrix....\n");
for(i = 0; i < 3; i++)
{
for( j = 0; j < 3; j++)
{
if( i <= j )
printf("%4d", a[ i ][ j ]);
else
printf("%4d", 0);
}
printf("\n");
}
break;
}
getch( );
}
String or Array of Characters: A string is a sequence of characters that is a single data item. Any group of characters
defined between double quotation marks is a string constant.
Example -
printf(“Hello world”);
Declaring and initializing string variables: C does not support strings as a data type. However, it allows us to represent strings as
character arrays. A string variable is also declared as an array of characters.
Syntax char variable[size];
Page 21
Example -
char x[20];
When the compiler assigns a character string to a character array, it automatically
supplies a NULL (‘\0’) character at the end of the string. Therefore, the size should be equal
to the maximum number of characters in the string plus one for ‘\0’ character.
Like numeric arrays, character arrays may be initialized when they are declared.
Example -
char x[20]={‘R’, ’A’, ’K’, ’E’, ’S’, ’H’, ’ ’, ’K’, ’U’, ’M’, ’A’, ’R’};
OR
char x[20]=“RAKESH KUMAR”;
C also permits us to initialize a character array without specifying the number of
elements. In such cases, the size of array will be determined automatically based on the
number of elements initialized.
Example -
char x[ ]={‘R’, ’A’, ’K’, ’E’, ’S’, ’H’, ’ ’, ’K’, ’U’, ’M’, ’A’, ’R’};
OR
char x[ ]=“RAKESH KUMAR”;
Reading string using scanf or gets: The scanf( ) function can be used with ‘%s’ format specification to read a string.
Example -
char x[20];
scanf(“%s”, x);
The problem with the ‘%s’ format character is that it terminates its input on first white
spaces it finds. The scanf function automatically terminates the string that is read with a null
character. We can also specify the field width using the form ‘%ws’ in the scanf( ) statement
for reading a specified number of characters from the input string.
Example -
char x[10];
scanf(“%5s”, x);
If you entered the string MANOHAR will be stored as: -
M
A
N
O
H
\0
0
1
2
3
4
5
6
7
8
9
We can read multiple words by using ‘%[^\n]’ character with scanf( ) function. We also use
gets( ) instead of scanf( ) function.
Example -
char x[20];
scanf(“%[^\n]”, x);
OR
gets(x);
Page 22
String Handling Functions: The C library supports a large number of string-handling functions that can be used to
carry out many of the string manipulations. The string handling functions are contained in
“string.h” header file.
1. strlen( ): - It calculates the length of string.
Syntax -
variable = strlen(string1);
2. strcpy( ): - It copies all characters of source string to destination string.
Syntax -
strcpy(destination-string, source-string);
3. strncpy( ): - It copies the given number of characters of source string to destination
string.
Syntax -
strncpy(destination-string, source-string, no-of-character);
4. strrev( ): - It reverses the string in the given string variable.
Syntax -
strrev(string1);
5. strcat( ): - It concatenates two strings.
Syntax -
strcat(destination-string, source-string);
6. strncat( ): - It merge the given number of character of source string at the end of
destination string.
Syntax -
strncat(destination-string, source-string, no-of-character);
7. strcmp( ): - This function compares two strings identified by the arguments and has a
value 0 if they are equal. If the ascii character of first string is greater than second
string then returns positive value and if the ascii character of first string is less than
second string then returns negative value.
Syntax strcmp(string1, string2);
8. strncmp( ): - This function compares the left-most n characters of first string to second
string and returns 0 if they are equal. It returns positive value, if the sub string of first
is greater than second string and it returns negative value, if the sub string of first is
less than second string.
Syntax -
strncmp(string1, string2, no-of-character);
9. strcmpi( ): - This function also compares two strings identified by the arguments
without case sensitivity. It returns 0 if they are equal. It returns positive value, if the
Page 23
first string is greater than second string and it returns negative value, if the first string
is less than second string.
Syntax -
strcmpi(string1, string2);
10. strstr( ): - It can be used to locate a sub string in a string. It will locate the first
occurrence of the sub string.
Syntax -
strstr(string, sub-string);
11. strchr( ): - It can be used to locate a character in a string. It will locate the first
occurrence of the character.
Syntax -
strchr(string, searching-character);
12. strrchr( ): - It can be used to locate the last occurrence of the character in the string.
Syntax -
strrchr(string, searching-character);
13. strupr( ): - It converts entire string into capital letters.
Syntax -
strupr(string);
14. strlwr( ): - It converts entire string into lower case letters.
Syntax -
strlwr(string);
Examples: 1. Write a program to calculate the length of string using user-defined function.
Ans.: #include<stdio.h>
#include<conio.h>
void main( )
{
int length(char [ ]);
char x[20];
int len;
clrscr( );
printf(“Enter the string – “);
scanf(“%[^\n]”, x);
len = length(x);
printf(“length of string = %d”, len);
getch( );
}
Page 24
int length(char a[ ])
{
int len=0, i;
for(i = 0; a[i] !=’\0’; i++)
len++;
return len;
}
2. Write a program to copy one string to another using user-defined function.
Ans.: #include<stdio.h>
#include<conio.h>
void main( )
{
void copystr(char [ ], char [ ]);
char x[20], y[20];
clrscr( );
printf(“Enter the string – “);
scanf(“%[^\n]”, x);
copystr(y, x);
printf(“copied string = %s”, y);
getch( );
}
void copystr(char dest[ ], char src[ ])
{ int i;
for(i = 0; src[i] !=’\0’; i++)
dest[i] = src[i];
dest[i] = ‘\0’;
}
Stack: A stack is a linear data structure in which data is inserted or deleted only at one end,
called the top of stack. Data is stored and retrieved in LIFO manner. The most recently
pushed element can be checked prior to performing a delete operation.
This means, in particular that elements are removed from a stack in the reverse order
of that in which they were inserted into the stack. Stacks are also known as Push down list.
Application of stacks: 1. Processing of sub-routine calls and their return.
2. Implementation of recursion.
3. Converting an expression from one form to another form.
E.g. - 2 + 3 
Infix
23+ 
Postfix
+23 
Prefix
4. Evaluation of expression.
Page 25
Operations on Stack: 1. Push elements in stack.
Push(stack, top, val)

which inserts the element val into the stack.
2. Pop elements from stack.
Pop(stack, top)

which removes the top element of stack and
return the element.
3. Read top position element from the stack.
Peep(stack, top)

which returns the top element of stack.
4. Check whether the stack is empty or not.
Isempty(stack, top)

which returns true, if stack is empty otherwise
returns false.
5. Check whether the stack is full or not.
Isfull(stack, top)

which returns true, if stack is full otherwise
returns false.
Implementation of Stack: To implement a stack, there are two common methods used: 1. Using Array
2. Using Linked List
1. Using Array Implementation: - The array implementation technique is very simple
and easy to implement. But there is one problem that we need to declare the size of an
array before start the operation. In this case, the actual number of elements in the
stack at any time never gets too large. It is usually easy to declare the array to be large
enough without wasting too much memory space. Associated with each stack there is
a top of stack that is -1 for empty stack.
Push operation: Push means to insert an item into the stack. In the push operation, first check if
the stack is full then insert operation is not possible and if the stack has blank elements then
insert the element.
Algorithm - push(stack, top, val)
Begin
If top = SIZE – 1 then
Display “Stack is full”
Else
top = top + 1
stack[top] = val
[End of if statement]
End
Page 26
Pop operation: The pop operation deletes the topmost item from the stack. After removal of
top most information, new value of the top pointer becomes the previous value of top of stack
i.e. top = top – 1 and freed position is allocated to free space.
Algorithm - pop(stack, top)
Begin
If top = – 1 then
Display “Stack is empty”
Else
x = stack[top]
top = top - 1
Return x
[End of if statement]
End
Peep or Peek operation: The peep operation only gets the information stored at the top of stack. In this
operation, top of stack never changes.
Algorithm - peep(stack, top)
Begin
If top = – 1 then
Display “Stack is empty”
Else
Return stack[top]
[End of if statement]
End
Determine the stack is empty operation: The isempty operation determines the stack is empty or not. If stack is empty
then return true otherwise false.
Algorithm - isempty(stack, top)
Begin
If top = – 1 then
Return 1
Else
Return 0
[End of if statement]
End
Determine the stack is full operation: The isfull operation determines the stack is full or not. If stack is full then
return true otherwise false.
Page 27
Algorithm - isfull(stack, top)
Begin
If top = SIZE – 1 then
Return 1
Else
Return 0
[End of if statement]
End
Example – Develop a program to perform all the operations on stack.
#include<stdio.h>
#include<conio.h>
#define SIZE 20
int stack[SIZE];
int top = -1;
void push(int);
int pop( );
int peep( );
int isempty( );
int isfull( );
void main( )
{
int ch, x;
clrscr( );
while(1)
{
printf(“\n 1. Push operation”);
printf(“\n 2. Pop operation”);
printf(“\n 3. Peep operation”);
printf(“\n 4. Determine the stack is empty”);
printf(“\n 5. Determine the stack is full”);
printf(“\n Enter the choice (0 for exit) - ”);
scanf(“%d”, &ch);
switch(ch)
{
case 1:
printf(“Enter the value – “);
scanf(“%d”, &x);
push(x);
break;
case 2:
printf(“Deleted element is = %d”, pop( ));
break;
case 3:
printf(“The top element is = %d”, peep( ));
Page 28
break;
case 4:
if(isempty( ))
printf(“Stack is empty”);
else
printf(“Stack is not empty”);
break;
case 5:
if(isfull( ))
printf(“Stack is full”);
else
printf(“Stack is not full”);
break;
case 0:
exit(0);
}
getch( );
}
}
void push(int val)
{
if(top = = SIZE – 1)
printf(“Stack is full”);
else
{
top = top + 1;
stack[top] = val;
}
}
int pop( )
{
int x;
if(top = = – 1)
{
printf(“Stack is empty”);
return -999;
}
else
{
x = stack[top];
top = top - 1;
return x;
}
}
int peep( )
Page 29
{
if(top = = – 1)
{
printf(“Stack is empty”);
return -999;
}
else
return stack[top];
}
int isempty( )
{
if(top = = – 1)
return 1;
else
return 0;
}
int isfull( )
{
if(top = = SIZE – 1)
return 1;
else
return 0;
}
Recursion: Recursion means the function call by itself. In the recursion, there is a condition
defined to exit from the function.
Example – Write algorithm and a program to calculate the factorial value of a number.
Algorithm – Fact(n)
Begin
If n = 1 Then
Return 1
Else
Return n * Fact(n - 1)
[End of if statement]
End.
#include<stdio.h>
#include<conio.h>
void main( )
{
int n;
float f;
float factorial(int);
Page 30
clrscr( );
printf(“Enter the number – “);
scanf(“%d”, &n);
f = factorial(n);
printf(“Factorial value is = %f ”, f);
getch( );
}
float factorial(int n)
{
if(n = = 1)
return 1;
else
return n * factorial(n-1);
}
Example – Write algorithm and develop a program to calculate the sum of digits of a number.
Algorithm – Sumofdigit(n)
Begin
If n = 0 Then
Return 0
Else
Return n%10 + Sumofdigit(n / 10)
[End of if statement]
End.
#include<stdio.h>
#include<conio.h>
void main( )
{
int n, s;
int sumofdigit(int);
clrscr( );
printf(“Enter the number – “);
scanf(“%d”, &n);
s = sumofdigit(n);
printf(“Sum of digits = %d ”, s);
getch( );
}
int sumofdigit(int n)
{
if(n = = 0)
return 0;
else
return n%10 + sumofdigit(n / 10);
}
Page 31
Example – Write algorithm and develop a program to calculate the linear search of a number.
Algorithm – Linearsearch(Arr, s, i, n)
Begin
If i < n Then
If s = Arr[i] Then
Return i + 1
Else
Return Linearsearch(Arr, s, i +1, n)
[End of if statement]
Else
Return -1
[End of if statement]
End.
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[10], n, i, s, flag;
int linearsearch(int [ ], int, int, int);
clrscr( );
printf(“How many numbers in an array – “);
scanf(“%d”, &n);
for(i = 0; i < n; i++)
{
printf(“Enter the number – “);
scanf(“%d”, &a[i]);
}
printf(“Enter the number to be searched – “);
scanf(“%d”, &s);
flag = linearsearch(a, 0, n, s);
if(flag = = -1)
printf(“Value not found”);
else
printf(“Value found on position = %d”, flag);
getch( );
}
int linearsearch(int arr[], int i, int n, int s)
{
if(i = = n)
return -1;
else
{
if(s = = arr[i])
return (i + 1);
Page 32
else
return linearsearch(arr, i+1, n, s);
}
}
Example – Develop a program to covert the decimal number into binary form using stack.
#include<stdio.h>
#include<conio.h>
#define SIZE 20
int stack[SIZE];
int top = -1;
void push(int);
int pop( );
void main( )
{
int x, r;
clrscr( );
printf(“Enter the value – “);
scanf(“%d”, &x);
while(x ! = 0)
{
r = x % 2;
push(r);
x = x / 2;
}
while(top ! = -1)
{
printf(“%d”, pop( ));
}
getch( );
}
void push(int val)
{
if(top = = SIZE – 1)
printf(“Stack is full”);
else
{
top = top + 1;
stack[top] = val;
}
}
int pop( )
{
int x;
if(top = = – 1)
Page 33
{
printf(“Stack is empty”);
return -999;
}
else
{
x = stack[top];
top = top - 1;
return x;
}
}
Example – Develop a program to determine the string is palindrome or not.
#include<stdio.h>
#include<conio.h>
#define SIZE 20
char stack[SIZE];
int top = -1;
void push(char);
char pop( );
void main( )
{
char x[20];
int i, len = 0, flag = 0;
clrscr( );
printf("Enter the string - ");
scanf("%s", x);
for(i = 0; x[i] != '\0' ; i++)
len++;
for(i = 0; i < len / 2 ; i++)
{
push(x[i]);
}
if(len%2 != 0)
i++;
while(top != -1)
{
if(x[i++] != pop( ))
{
flag = 1;
break;
}
}
if(flag = = 0)
printf("String is palindrome");
Page 34
else
printf("String is not palindrome");
getch( );
}
void push(char val)
{
if(top = = SIZE - 1)
printf("Stack is full");
else
{
top = top + 1;
stack[top] = val;
}
}
char pop( )
{
int x;
if(top = = - 1)
{
printf("Stack is empty");
return -999;
}
else
{
x = stack[top];
top = top - 1;
return x;
}
}
Polish Notation: This is the operation of written the expression where operators come before the
operands i.e. variable or constant is called polish notation or prefix order of expression.
Reverse Polish Notation: This is the operation of written the expression where operators come after the
operands i.e. variable or constant is called reverse polish notation or postfix order of
expression.
Conversion from Infix to Postfix and Infix to Prefix expression: Infix
a+b
a+b*c
a*b+c
Prefix
+ab
+a*bc
+*abc
Postfix
ab+
abc*+
ab*c+
Page 35
(a+b)*c
(a+b)*(c-d)
*+abc
*+ab-cd
ab+c*
ab+cd-*
Example – Develop a program to convert the infix to postfix expression.
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#define SIZE 20
char stack[SIZE];
int top=-1;
void push(char);
char pop( );
char peep( );
int priority(char);
void main()
{
char x[20], y[20];
int i, j=0;
clrscr( );
printf("enter the infix expression - ");
gets(x);
for(i = 0; x[i] !='\0'; i++)
{
if(isalnum(x[i]))
y[j++] = x[i];
else if(x[i] = = '(' )
push(x[i]);
else if(x[i] = = ')' )
{
if(top != -1)
{
while(peep( ) != '(' )
y[ j++ ]=pop( );
}
pop( );
}
else if(x[i] = = '+' || x[i] = = '-' || x[i] = = '*' || x[i] = = '/' || x[i] = = '%')
{
if(top != -1)
{
if(priority(x[i])<=priority(peep( )))
y[ j++ ]=pop( );
}
push(x[i]);
}
Page 36
}
while(top != -1)
y[j++]=pop( );
y[j] = '\0';
printf("postfix expression = %s", y);
getch();
}
void push(char val)
{
if(top = = SIZE-1)
printf("stack is full");
else
{
top++;
stack[top] = val;
}
}
char pop( )
{
char t;
if(top = = -1)
{
printf("stack is empty");
return -999;
}
else
{
t=stack[top];
top--;
return t;
}
}
char peep( )
{
if(top = = -1)
{
printf("stack is empty");
return -999;
}
else
{
return stack[top];
}
}
Page 37
int priority(char op)
{
switch(op)
{
case '(':
return 0;
case '+': case '-':
return 1;
case '%':
return 2;
case '*': case '/':
return 3;
}
}
Example – Develop a program to convert the infix to prefix expression.
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#define SIZE 20
char stack[SIZE];
int top=-1;
void push(char);
char pop( );
char peep( );
int priority(char);
void main()
{
char x[20], y[20];
int i, j=0, l=0;
clrscr( );
printf("enter the infix expression - ");
gets(x);
for(i = 0; x[i] !='\0'; i++)
l++;
for(i = l-1; i >= 0; i--)
{
if(isalnum(x[i]))
y[j++] = x[i];
else if(x[i] = = ')' )
push(x[i]);
else if(x[i] = = '(' )
{
if(top != -1)
{
Page 38
while(peep( ) != ')' )
y[ j++ ]=pop( );
}
pop( );
}
else if(x[i] = = '+' || x[i] = = '-' || x[i] = = '*' || x[i] = = '/' || x[i] = = '%')
{
if(top != -1)
{
if(priority(x[i])<=priority(peep( )))
y[ j++ ]=pop( );
}
push(x[i]);
}
}
while(top != -1)
y[j++]=pop( );
y[j] = '\0';
strrev(y);
printf("prefix expression = %s", y);
getch();
}
void push(char val)
{
if(top = = SIZE-1)
printf("stack is full");
else
{
top++;
stack[top] = val;
}
}
char pop( )
{
char t;
if(top = = -1)
{
printf("stack is empty");
return -999;
}
else
{
t=stack[top];
top--;
Page 39
return t;
}
}
char peep( )
{
if(top = = -1)
{
printf("stack is empty");
return -999;
}
else
{
return stack[top];
}
}
int priority(char op)
{
switch(op)
{
case ')':
return 0;
case '+': case '-':
return 1;
case '%':
return 2;
case '*': case '/':
return 3;
}
}
Queue: A queue is a collection of linear data structure in which insertion of elements can take
place only at one end called REAR and deletion of elements can take place only at other end
called FRONT. This makes the queue a First-In-First-Out data structure. In a FIFO data
structure, the first element added to the queue will be the first one to be removed.
For example – A queue of people waiting at a ticket window or at bus stop, each new
person who comes, takes his place at the end of line. The people in the front take the ticket
first. Thus queue are also called FIFO structure.
Implementation of Queue: Queue can be implemented in two ways: 1. Array or Static implementation
2. Linked list or Dynamic implementation.
Page 40
Array or Static implementation: It uses array to create queue. Static implementation is the most widely used technique.
But it is not efficient with respect to memory utilization because in static implementation, the
size of queue has to be declared during program design. Now if there are few elements to be
stored in the queue, some allocated memory will be wasted and we will not be able to
decrease the size of array. If there are a large number of elements to be stored in the queue,
then we will not be able to increase the size of array.
Linked list or Dynamic implementation: It is done using linked list that uses pointers to implement the queue. The size of
queue varies according to requirement.
Representation of Queue: The representation of queue can be in various ways, sometimes through one-way list
and sometimes through linear arrays. It is maintained as linear arrays with two pointer
variables FRONT and REAR.
FRONT: - It contains the location of the front element in the queue.
REAR: - It contains the location of the last element in the queue.
When the element is deleted from the queue the value of FRONT is increased by 1.
FRONT = FRONT + 1
FRONT =1
REAR = 4
1
2
3
4
A
B
C
D
5
6
7
8
9
6
7
8
9
Queue
A is deleted from queue
FRONT =2
REAR = 4
1
2
3
4
B
C
D
5
Queue
When an element is added-up to the queue then the value of REAR is increased by 1.
REAR = REAR + 1
1
2
3
4
5
6
7
8
9
FRONT =2
B
C
D
REAR = 4
Queue
E is added to queue
FRONT =2
REAR = 5
1
2
3
4
5
B
C
D
E
6
7
8
9
Operations on queue: 1. Insert an element in the queue: This operation is called Enqueue operation. When an element is added to
queue, first it must check whether the queue is full or not. If queue is full, this
Page 41
condition is called QUEUE OVERFLOW. If queue is not full, item should be added
at the rear. After every insertion, the rear increments by one. When first item is added
to queue, front must be set to zero.
Algorithm – Insert an item in queue
Begin
If FRONT = 0 and REAR = SIZE – 1 Then
Display “Queue Overflow” and return
Else
if FRONT = -1 Then
FRONT = 0
REAR = 0
Else
REAR = REAR + 1
[End of if statement]
Q[REAR] = val
[End of if statement]
End
2. Delete an element from the queue: This operation is called Dequeue operation. When an element is removed from
queue, it should first check whether the queue is empty or not. If queue is empty, this
condition is called QUEUE UNDERFLOW. If the queue is not empty, then the
element should be removed from the FRONT. After each deletion the FRONT should
be incremented by 1.
Algorithm – Delete an item from queue
Begin
If FRONT = -1 Then
Display “Queue Underflow” and return
Else
val = Q[FRONT]
if FRONT = REAR Then
FRONT = -1
REAR = -1
Else
FRONT = FRONT + 1
[End of if statement]
Return(val)
[End of if statement]
End
Page 42
3. Traverse the queue: When the queue is traversed, it should first check whether the queue is empty
or not. If queue is empty, this condition is called QUEUE UNDERFLOW. If the
queue is not empty, then access each element starting from FRONT to REAR.
Algorithm – Traverse the queue
Begin
If FRONT = -1 Then
Display “Queue Underflow” and return
Else
For i = FRONT to REAR Step 1
Display Queue[i]
[End of for statement]
[End of if statement]
End
4. Determine the queue is full or not: This operation determines whether the queue is full or not. If FRONT is
positioned on 0 and REAR on SIZE-1 then the queue is full, this condition is called
QUEUE OVERFLOW. Otherwise not full.
Algorithm – Determine the queue is full or not
Begin
If FRONT = 0 and REAR = SIZE – 1 Then
Display “Queue Overflow”
Else
Display “Queue Not Overflow”
[End of if statement]
End
5. Determine the queue is empty: This operation determines whether the queue is empty or not. If the FRONT is
positioned on -1 then the queue is empty, this condition is called QUEUE
UNDERFLOW. Otherwise not empty.
Algorithm – Determine the queue is empty or not
Begin
If FRONT = -1 Then
Display “Queue Underflow”
Else
Display “Queue Not Underflow”
[End of if statement]
End
Page 43
Example – Develop a program to perform all the operations on linear queue.
#include<stdio.h>
#include<conio.h>
#define SIZE 20
int Q[SIZE];
int front = -1, rear = -1;
void enqueue(int);
int dequeue( );
void display( );
void isempty( );
void isfull( );
void main( )
{
int ch, x;
clrscr( );
while(1)
{
printf("\n Queue Operations");
printf("\n 1. Insert operation");
printf("\n 2. Delete operation");
printf("\n 3. Display the values");
printf("\n 4. Determine the queue is empty");
printf("\n 5. Determine the queue is full");
printf("\n Enter the choice (0 for exit) - ");
scanf("%d", &ch);
switch(ch)
{
case 1:
printf("Enter the value - ");
scanf("%d", &x);
enqueue(x);
break;
case 2:
printf("Deleted element is = %d", dequeue( ));
break;
case 3:
display( );
break;
case 4:
isempty( );
break;
case 5:
isfull( );
break;
case 0:
Page 44
exit(0);
}
getch( );
}
}
void enqueue(int val)
{
if(front = = 0 && rear = = SIZE - 1)
{
printf("Queue Overflow");
return;
}
else if(front = = -1)
front = rear = 0;
else
rear++;
Q[rear] = val;
}
int dequeue( )
{
int x;
if(front = = - 1)
printf("Queue Underflow");
else
{
x = Q[front];
if(front = = rear)
front = rear = -1;
else
front++;
return x;
}
}
void display( )
{
int i;
if(front = = - 1)
printf("Queue Underflow");
else
{
for(i = front; i <= rear; i++)
printf("\n %d", Q[i]);
}
}
Page 45
void isempty( )
{
if(front = = - 1)
printf("Queue Underflow");
else
printf("Queue Not Underflow");
}
void isfull( )
{
if(front = = 0 && rear = = SIZE - 1)
printf("Queue Overflow");
else
printf("Queue Not Overflow");
}
Circular Queue: An array ‘Queue’ that contains n elements in which Queue[0] comes after
Queue[SIZE-1] in the array. When this technique is used to construct a queue then the queue
is called Circular queue. In other words, a queue is called circular when the last element
comes just before the first element.
In a circular queue, when REAR = SIZE – 1, if we insert an element then this element
is assigned to Queue[0]. That is instead of increasing REAR to REAR + 1, we reset REAR to
0.
Similarly, if FRONT = SIZE – 1 and an element of the queue is deleted, we reset
FRONT to 0 instead of FRONT + 1.
When the element is removed if both are pointed on same position then the FRONT
and REAR are assigned to -1 to indicate that the queue is empty.
Insert an element in the queue (Enqueue): Algorithm – Insert an item in circular queue
Begin
If (FRONT = 0 and REAR = SIZE – 1) or (FRONT = REAR+1) Then
Display “Queue Overflow” and return
Else if FRONT = -1 Then
FRONT = 0
REAR = 0
Else if REAR = SIZE – 1 Then
REAR = 0
Else
REAR = REAR + 1
[End of if statement]
Queue[REAR] = val
End
Page 46
Delete an element from the queue (Dequeue): Algorithm – Delete an item from circular queue
Begin
If FRONT = -1 Then
Display “Queue Underflow” and return
Else
val = Queue[FRONT]
If FRONT = REAR Then
FRONT = -1
REAR = -1
Else if FRONT = SIZE – 1 Then
FRONT = 0
Else
FRONT = FRONT + 1
[End of if statement]
Return(val)
[End of if statement]
End
Traverse the queue: Algorithm – Traverse the circular queue
Begin
If FRONT = -1 Then
Display “Queue Underflow” and return
Else if REAR >= FRONT Then
For i = FRONT to REAR Step 1
Display Queue[i]
[End of for statement]
Else
For i = FRONT to SIZE – 1 Step 1
Display Queue[i]
[End of for statement]
For i = 0 to REAR Step 1
Display Queue[i]
[End of for statement]
[End of if statement]
End
Example – Develop a program to perform all the operations on circular queue.
#include<stdio.h>
#include<conio.h>
#define SIZE 20
int Q[SIZE];
Page 47
int front = -1, rear = -1;
void enqueue(int);
int dequeue( );
void display( );
void main( )
{
int ch, x;
clrscr( );
while(1)
{
printf("\n Circular Queue Operations");
printf("\n 1. Insert operation");
printf("\n 2. Delete operation");
printf("\n 3. Display the values");
printf("\n Enter the choice (0 for exit) - ");
scanf("%d", &ch);
switch(ch)
{
case 1:
printf("Enter the value - ");
scanf("%d", &x);
enqueue(x);
break;
case 2:
printf("Deleted element is = %d", dequeue( ));
break;
case 3:
display( );
break;
case 0:
exit(0);
}
getch( );
}
}
void enqueue(int val)
{
if(front = = 0 && rear = = SIZE - 1)
{
printf("Queue Overflow");
return;
}
else if(front = = -1)
front = rear = 0;
Page 48
else if(rear = = SIZE - 1)
rear = 0;
else
rear++;
Q[rear] = val;
}
int dequeue( )
{
int x;
if(front = = - 1)
printf("Queue Underflow");
else
{
x = Q[front];
if(front = = rear)
front = rear = -1;
else if(front = = SIZE - 1)
front = 0;
else
front++;
return x;
}
}
void display( )
{
int i;
if(front = = - 1)
printf("Queue Underflow");
else if(rear >= front)
{
for(i = front; i <= rear; i++)
printf("\n %d", Q[i]);
}
else
{
for(i = front; i <= SIZE - 1; i++)
printf("\n %d", Q[i]);
for(i = 0; i <= rear; i++)
printf("\n %d", Q[i]);
}
}
Page 49
Deque (Double Ended Queue): It is a linear list in which insertion and deletions are possible at either front or rear end
but not from the middle. Deque is known as Double Ended Queue. Deque is more superior
representation of linear list. There are two forms of Deque:  Input restricted deque
 Output restricted deque
1. Input restricted deque: - In this form of deque, insertion can possible only at rear end,
but the deletion operation perform on both sides.
2. Output restricted deque: - In this form of deque, deletion can possible only at front
end, but the insertion operation perform on both sides.
Insert an element in the deque: Algorithm – Insert an item in deque
Begin
If FRONT = 0 and REAR = SIZE – 1 Then
Display “Queue Overflow” and return
Else If FRONT = - 1 Then
FRONT = REAR = 0
Queue[REAR] = val
Else If FRONT > 0 Then
FRONT = FRONT – 1
Queue[FRONT] = val
Else if REAR < SIZE – 1 Then
REAR = REAR + 1
Queue[REAR] = val
[End of if statement]
End
Delete an element from the deque: Algorithm – Delete an item from double ended queue
Begin
If FRONT = -1 Then
Display “Queue Underflow” and return
Else If FRONT > -1 Then
val = Queue[FRONT]
If FRONT = REAR Then
FRONT = -1
REAR = -1
Else
FRONT = FRONT + 1
[End of if statement]
Else If REAR > -1 Then
val = Queue[REAR]
Page 50
If FRONT = REAR Then
FRONT = -1
REAR = -1
Else
REAR = REAR - 1
[End of if statement]
[End of if statement]
Return(val)
End
Example – Develop a program to perform all the operations on deque.
#include<stdio.h>
#include<conio.h>
#define SIZE 20
int Q[SIZE];
int front = -1, rear = -1;
void enqueue(int);
int dequeue( );
void display( );
void main( )
{
int ch, x;
clrscr( );
while(1)
{
printf("\n Double Ended Queue Operations");
printf("\n 1. Insert operation");
printf("\n 2. Delete operation");
printf("\n 3. Display the values");
printf("\n Enter the choice (0 for exit) - ");
scanf("%d", &ch);
switch(ch)
{
case 1:
printf("Enter the value - ");
scanf("%d", &x);
enqueue(x);
break;
case 2:
printf("Deleted element is = %d", dequeue( ));
break;
case 3:
display( );
break;
Page 51
case 0:
exit(0);
}
getch( );
}
}
void enqueue(int val)
{
if(front = = 0 && rear = = SIZE - 1)
{
printf("Queue Overflow");
return;
}
else if(front = = -1)
{
front = rear = 0;
Q[rear] = val;
}
else if(front > 0)
{
front--;
Q[front] = val;
}
else if(rear < SIZE - 1)
{
rear++;
Q[rear] = val;
}
}
int dequeue( )
{
int x;
if(front = = - 1)
printf("Queue Underflow");
else if(front > -1)
{
x = Q[front];
if(front = = rear)
front = rear = -1;
else
front++;
}
else if(rear > -1)
{
x = Q[rear];
Page 52
if(front = = rear)
front = rear = -1;
else
rear--;
}
return x;
}
void display( )
{
int i;
if(front = = - 1)
printf("Queue Underflow");
else
{
for(i = front; i <= rear; i++)
printf("\n %d", Q[i]);
}
}
Priority Queue: A priority queue is a collection of elements where the elements are processed
according to their priorities. The order in which the elements will be inserted or deleted is
decided is decided by the following rules: 1. An element of higher priority is processed before any element of lower priority.
2. Two elements with the same priority are processed according to the order in which
they are added to the queue.
Priority queues are used for implementing job scheduling in a time sharing operating
system, where jobs with higher priorities are to be processed first.
Implementation of queue using Linked list: When we implement the queue using an array, this data structure had the basic
limitations of the array; that is the size cannot be increased or decreased, once it is declared.
This difficulty is eliminated when we implement queue using linked lists. In case of linked
queue we shall add elements to the queue at the end of the linked list, whereas, we shall
delete elements from the beginning of the linked list.
Example –
struct Queue
{
int data;
struct Queue *next;
}*Front, *Rear;
Each such queue contains an integer field and a pointer to the next queue element in
the linked list. The pointer Front will use to delete the elements from beginning of the linked
Page 53
list and the pointer Rear will use to add elements to the queue at the end of the linked list.
When the list is empty, Front and Rear will contain NULL.
Algorithm to insert an item in the queue: Algorithm – insert(val)
Let Queue be a structure (node) having a ‘Data’ field and another field ‘Next’ address
pointer which contains the address of next element is queue. The two global variables
Front and Rear for implement the queue.
Begin
Temp = Create a node
Temp [Data] = val
Temp [Next] = NULL
If Front = NULL Then
Front = Rear = Temp
Else
Rear [Next] = Temp
Rear = Temp
[End of if statement]
End
Algorithm to delete an item from the queue: Algorithm – deletenode(val)
Let Queue be a structure (node) having a ‘Data’ field and another field ‘Next’ address
pointer which contains the address of next element is queue. The two global variables
Front and Rear for implement the queue.
Begin
If Front = NULL Then
Write “Queue Underflow” and Exit
Else
Ptr = Front
val = Front [Data]
Front = Front [Next]
Free (Ptr)
Return (val)
[End of if statement]
End
Example – Write a program of Queue operations using linked list.
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
struct Queue
{
int data;
Page 54
struct Queue *next;
}*front, *rear;
typedef struct Queue Queue;
void insert(int);
int deletenode( );
void display( );
void main( )
{
int ch, x;
front = rear = NULL;
clrscr( );
while(1)
{
printf("\n Queue Operations");
printf("\n 1. Insert operation");
printf("\n 2. Delete operation");
printf("\n 3. Display the values");
printf("\n Enter the choice (0 for exit) - ");
scanf("%d", &ch);
switch(ch)
{
case 1:
printf("Enter the value - ");
scanf("%d", &x);
insert(x);
break;
case 2:
x = deletenode( );
printf("Deleted element is = %d", x);
break;
case 3:
display( );
break;
case 0:
exit(0);
}
getch( );
}
}
void insert(int val)
{
Queue *temp;
temp = (Queue *)malloc(sizeof(Queue));
temp -> data = val;
Page 55
temp -> next = NULL;
if(front = = NULL)
front = rear = temp;
else
{
rear->next = temp;
rear = temp;
}
}
int deletenode( )
{
Queue *ptr;
int val;
if(front = = NULL)
printf("Queue Underflow");
else
{
ptr = front;
val = front->data;
front = front->next;
free(ptr);
return val;
}
}
void display( )
{
Queue *ptr;
if(front = = NULL)
printf("Queue Underflow");
else
{
for(ptr = front; ptr != NULL; ptr = ptr->next)
printf("%d -> ", ptr->data);
}
}
Similarities between Stacks and Queues: 1. Both are data structures in which insertion and deletion operations are restricted to
ends only.
2. Both can be implemented using arrays and linked list.
3. Both use temporary memory location.
4. Both have standard functions for inserting and deleting elements.
Page 56
Linked List: Array data structure is simple to understand; time to access any element from an array
is constant. But some limitations can also be attributed to its simple structure. First, the size
of an array has to be defined when the program is being written and its space is reserved
during compilation of program. This means that the programmer has to decide the maximum
size of array that can not vary during run time. The second problem in array is if we assign
less values rather than their size then the remaining memory space would be wasted. We
cannot insert exceed values rather than their size and the occupied memory address will not
be deleted at run time if not used. To overcome such difficulties we use linked list.
Linked list is a way to store the data. It is a linear collection of data element in which
each data element points to next element. Data element is also called node. A node is a basic
element of a linked list. Each node is divided in two parts: The first part contains the information of the element and the second part contains a
pointer which points the address of the next node in the linked list called link field or nextpointer field.
Representation of a linked list: struct node
{
int data;
struct node *next;
};
A structure node defines a new data type, in which a data item of integer type and a
pointer to the next node in the linked list. The pointer start will always point to the first node.
When the list is empty, start contains NULL.
Start
14
6
17
8
X
Static and Dynamic memory allocations: In some data structures, we need to allocate memory before running the program, like
incase simple variable declarations as int, float or in case of complex data structures as array
declarations. In such cases, we should know in advance that how much memory we will need
in program and this is practically not possible in some cases. Such memory allocations are
called Static memory allocations and these data structures are static data structures.
There may be some data structures which need memory to be allocated on run time
like linked list etc. Such memory allocation technique is called dynamic memory allocation.
Dynamic data structure provides flexibility in adding and deletion data items at running time.
Dynamic memory management permits us to allow additional memory space or to release
unwanted space at run time.
Disadvantages of Static memory allocation: Page 57
1. Specifying size in advance: We have to specify the size of the array i.e. the size of memory allocation
while writing the program. In such cases there may be wastage of memory, if quantity
of available data is less than that of declared size or there may be shortage of memory,
if quantity of data to be stored is larger than that of declared size.
2. Memory remain allocated throughout program: There may be variables which were in use in starting of program, but program
may not use them later, in such cases, the variables remain allocated throughout its
execution.
Functions of Dynamic memory allocation: 1. sizeof( ): This function gives the size occupied of its argument in bytes. The argument
can be variable, constant, array or any data type.
Syntax –
sizeof(operand)
2. malloc( ): This function is used to allocate memory space. It allocates a memory space of
specified size and gives the starting address to pointer variable.
Syntax –
pointer-var = (data-type *) malloc(specified size);
3. calloc( ): This function is used to allocate multiple blocks of memory. It initializes them
to zero and then returns a pointer to the memory. This function generally used for
allocating the memory space for array and structure.
Syntax –
pointer-var = (data-type *) calloc(nitems, size of each item);
4. free( ): We can release the memory space that is not required. We can use free( )
function for releasing the memory space.
Syntax –
free(pointer-var);
5. realloc( ): There are two possibilities when we want to change the size of the block. In
first case, we want more memory space rather than allocated memory space. In
second case, the allocated memory space is more than the required memory space. For
changing the size of memory block we can use the realloc( ) function.
Syntax –
pointer-var = realloc(pointer-var, newsize);
Advantages of Linked list over Array: 1. In the linked list, we do not need to know in advance the number of elements that will
be require. While in array, we would need to allocate all the storage on the program
will be started.
2. With a linked list, we can allocate memory for an element dynamically, when we need
it, leading to efficient utilization of memory.
3. In linked list, it is easier to insert or delete items by rearranging the pointers but in
array insertion or deletion requires large amount of data.
4. Linked list can grow or shrink in size during the execution of program.
Page 58
Disadvantages of Linked list over Array: 1. A linked list will use more memory storage than array with the same number of
elements is used because each time linked list has more memory for an additional
linked field.
2. Array elements can be randomly accessed by giving appropriate index, while linked
list elements cannot be randomly accessed.
3. A linked list takes more time in traversing of elements.
4. Binary search cannot be applied in a linked list.
Types of Linked list: There are three types of linked list: 1. Single or Linear or One-way linked list
In a single linked list, each node has a data part and one link part which
contains the address of next node in the list. It is only traverse in one-way direction.
2. Double or Two-way linked list
In a doubly linked list, each node has one data field and has two link field i.e.
next pointer and previous pointer. The next pointer contains the address of next node
in the list and previous pointer contains the address of the previous node in the list. It
also allows reverse traversal in the linked list.
3. Circular linked list
a. Single Circular linked list: A circular linked list is a singly linked list in which link field of the last
node contains the address of the first node of the list, instead of NULL. The
coupling between each and every elements of the list becomes a cyclic.
b. Double Circular linked list: A double circular linked list is one which has two link fields i.e. next
pointer and previous pointer in circular manner. The next pointer of last node
points to the first node while the previous pointer of the first node point to the
last node in the linked list.
Page 59
Linked List operations: There are several operations that can be performed on linked list as follows: 1. Creation of a linked list
2. Traversing of a linked list
3. Counting the nodes in linked list
4. Insertion in linked list
5. Deletion in linked list
6. Searching a node in linked list
7. Sorting a linked list
8. Merging two linked list
Single linked list: Creation of a linked list: There are two methods of creating single linked list: a. Using stack
b. Using queue
a.) Using stack: The stack is a LIFO order list. To create a linked list using stack, follow the steps:
1. Create a memory allocation for new TEMP node.
2. Assign the value to the data part of TEMP node.
3. Assign the START to the next pointer of TEMP node.
4. Now assign the START on TEMP node.
Algorithm: - Create-by-stack(Start, val)
Begin
Temp = create a node
Temp [Data] = val
Temp [Next] = Start
Start = Temp
End
b.) Using queue: The queue is a FIFO order list. To create a linked list using queue, follow the
steps: 1. Create a memory allocation for new TEMP node.
2. Assign the value to the data part of TEMP node.
3. Assign the NULL to the next pointer of TEMP node.
Page 60
4. Check if the list is empty then assign the address of TEMP node to START.
5. If list is not empty then first traverse each node of list until end of list does not
encountered. Then insert the new node TEMP at the end of list.
Algorithm: - Create-by-queue(Start, val)
Begin
Temp = create a node
Temp [Data] = val
Temp [Next] = NULL
If Start = NULL Then
Start = Temp
Else
Ptr = Start
While Ptr [Next] != NULL do
Ptr = Ptr [Next]
[End of while statement]
Ptr [Next] = Temp
[End of if statement]
End
Traversing a linked list: Traversing of linked list means accessing each node’s data exactly once. Traversing
may be displaying, adding, squaring or any processing of each node’s data. To display the
elements of linked list, follow the steps: 1. Firstly assign a temporary pointer ‘Ptr’ to ‘Start’ node.
2. Traverse the each node of linked list until the ‘Ptr’ has NULL address.
Algorithm: - Traverse(Start)
Begin
If Start = NULL Then
Display “List is Empty”
Else
Ptr = Start
While Ptr != NULL do
Display Ptr [Data]
Ptr = Ptr [Next]
[End of while statement]
[End of if statement]
End
Example – Write a program to create a singly linked list using stack and display the
elements.
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
Page 61
struct node
{
int data;
struct node *next;
};
typedef struct node node;
node *create(node *, int);
void display(node *);
void main( )
{
int x;
node *start = NULL;
clrscr( );
while(1)
{
printf("Enter the number (Type 0 for Exit) - ");
scanf("%d", &x);
if(x = = 0)
break;
start = create(start, x);
}
display(start);
getch( );
}
node *create(node *start, int val)
{
node *temp;
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->next = start;
start = temp;
return start;
}
void display(node *start)
{
node *ptr = start;
if(start = = NULL)
printf("List is empty");
else
{
while(ptr != NULL)
{
printf("%d -> ", ptr->data);
ptr = ptr->next;
Page 62
}
}
}
Example – Write a program to create a singly linked list using queue and display the
elements.
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
struct node
{
int data;
struct node *next;
};
typedef struct node node;
node *create(node *, int);
void display(node *);
void main( )
{
int x;
node *start = NULL;
clrscr( );
while(1)
{
printf("Enter the number (Type 0 for Exit) - ");
scanf("%d", &x);
if(x = = 0)
break;
start = create(start, x);
}
display(start);
getch( );
}
node *create(node *start, int val)
{
node *temp, *ptr;
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->next = NULL;
if(start = = NULL)
start = temp;
else
{
ptr = start;
while(ptr->next != NULL)
Page 63
ptr = ptr->next;
ptr->next = temp;
}
return start;
}
void display(node *start)
{
node *ptr = start;
if(start = = NULL)
printf("List is empty");
else
{
while(ptr != NULL)
{
printf("%d -> ", ptr->data);
ptr = ptr->next;
}
}
}
Counting the nodes in a linked list: In this operation, the nodes are counted by traversing each node of linked list without
disturbing the ‘Start’ pointer and take a count variable which is incremented by 1 until the
‘Ptr’ reaches the NULL address.
Algorithm: - Counting(Start)
Begin
If Start = NULL Then
Display “List is Empty”
Else
Count = 0
Ptr = Start
While Ptr != NULL do
Count = Count + 1
Ptr = Ptr [Next]
[End of while statement]
Return (Count)
[End of if statement]
End
Inserting a node in linked list: The insertion operation is classified into following three categories: 1. Insert at first node
2. Insert at last node
3. Insert at given position
Page 64
1.) Insert at first node: - To insert a node at the beginning of a linked list follow the
following steps: a. First create a memory allocation for new TEMP node.
b. Assign the value to the data part of TEMP node.
c. Assign the address of first node to the next pointer of TEMP node.
d. Make the new node as the first node in the list by assigning the START on TEMP
node.
Algorithm: - Insert-at-first(Start, val)
Begin
Temp = create a node
Temp [Data] = val
Temp [Next] = Start
Start = Temp
End
2.) Insert at last node: - To insert a node at the end of a linked list follow these steps: a. First create a memory allocation for new TEMP node.
b. Assign the value to the data part of TEMP node.
c. Assign the NULL to the next pointer of TEMP node.
d. First traverse each node of list until end of list does not encountered. Then insert
the new node TEMP at the end of list.
Algorithm: - Insert-at-last(Start, val)
Begin
Temp = create a node
Temp [Data] = val
Temp [Next] = NULL
If Start = NULL Then
Start = Temp
Else
Ptr = Start
While Ptr [Next] != NULL do
Ptr = Ptr [Next]
[End of while statement]
Ptr [Next] = Temp
[End of if statement]
End
3.) Insert at given position: - To insert a node at the specified position of a linked list
follow the steps: a. First create a memory allocation for new TEMP node.
b. Assign the value to the data part of TEMP node.
c. Firstly obtain the desired position of node by traversing the linked list.
d. Make the link field of new node to point the next node.
Page 65
e. Assign the address of inserted node into the link part of the previous node.
Algorithm: - Insert-at-given-position(Start, val, pos)
Begin
Temp = create a node
Temp [Data] = val
Ptr = Start
For i = 1 to pos – 2 Step 1
Ptr = Ptr [Next]
[End of while statement]
Temp [Next] = Ptr [Next]
Ptr [Next] = Temp
End
Example – Write a program to create a singly linked list, insert the elements and display
them.
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
struct node
{
int data;
struct node *next;
};
typedef struct node node;
node *create(node *,int);
void display(node *);
node *insertatfirst(node *, int);
node *insertatlast(node *, int);
node *insertatposition(node *, int, int);
void main( )
{
int x, ch, p;
node *start = NULL;
clrscr( );
while(1)
{
printf("Enter the number (Type 0 for Exit) - ");
scanf("%d", &x);
if(x = = 0)
break;
start=create(start, x);
}
display(start);
do
Page 66
{
printf("\n 1. Insert at first");
printf("\n 2. Insert at last");
printf("\n 3. Insert at given position");
printf("\n Enter the choice - ");
scanf("%d",&ch);
switch(ch)
{
case 1:
printf("Enter the new value - ");
scanf("%d", &x);
start = insertatfirst(start, x);
break;
case 2:
printf("Enter the new value - ");
scanf("%d", &x);
start = insertatlast(start, x);
break;
case 3:
printf("Enter the new value - ");
scanf("%d", &x);
printf("Enter the position - ");
scanf("%d", &p);
start = insertatposition(start, x, p);
break;
}
}while(ch>=1 && ch<=3);
display(start);
getch( );
}
node *create(node *start, int val)
{
node *temp, *ptr;
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->next = NULL;
if(start = = NULL)
start = temp;
else
{
ptr = start;
while(ptr->next != NULL)
ptr = ptr->next;
ptr->next = temp;
}
Page 67
return start;
}
void display(node *start)
{
node *ptr = start;
if(start = = NULL)
printf("List is empty");
else
{
while(ptr != NULL)
{
printf("%d -> ", ptr->data);
ptr = ptr->next;
}
}
}
node *insertatfirst(node *start, int val)
{
node *temp;
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->next = start;
start = temp;
return start;
}
node *insertatlast(node *start, int val)
{
node *temp, *ptr = start;
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->next = NULL;
while(ptr->next != NULL)
ptr = ptr->next;
ptr->next = temp;
return start;
}
node *insertatposition(node *start, int val, int pos)
{
node *temp, *ptr = start;
int i;
temp = (node *)malloc(sizeof(node));
temp->data = val;
for(i = 1; i < pos - 1; i++)
ptr = ptr->next;
Page 68
temp->next = ptr->next;
ptr->next = temp;
return start;
}
Deletion in linked list: The deletion operation is classified into following three categories: 1. Delete from first node
2. Delete from last node
3. Delete from given position
1.) Delete from first node: - To delete a node from the beginning of a linked list follow
these steps: a. Firstly check if the list is empty then give the appropriate message otherwise do
the next steps.
b. First point a temporary pointer Ptr to Start node.
c. Assign the next pointer of Start address to the Start.
d. Deallocate the Ptr pointer.
Algorithm: - Delete-from-first(Start)
Begin
If Start = NULL Then
Display “List is empty”
Else
Ptr = Start
Start = Start [Next]
Free (Ptr)
[End of if statement]
End
2.) Delete from last node: - To delete a node from the end of a linked list follow the
following steps: a. Firstly check if the list is empty then give the appropriate message otherwise do
the next steps.
b. First point a temporary pointer ‘Ptr’ to Start node.
c. Traverse the linked list till the last node and take another pointer Ptr1 which points
to the previous node of the current node ‘Ptr’.
d. Assign the NULL to next pointer of second last node ‘Ptr1’.
e. Deallocate the Ptr pointer.
Algorithm: - Delete-from-last(Start)
Begin
If Start = NULL Then
Display “List is empty”
Page 69
Else
Ptr = Start
While Ptr [Next] != NULL
Ptr1 = Ptr
Ptr = Ptr [Next]
[End of while statement]
Ptr1 [Next] = NULL
Free (Ptr)
[End of if statement]
End
3.) Delete node from the given position: - To delete a node from the given position of a
linked list follow these steps: a. Firstly check if the list is empty then give the appropriate message otherwise do
the next steps.
b. First point a temporary pointer ‘Ptr’ to Start node.
c. Firstly obtain the desired position of node by traversing the linked list.
d. The other pointer Ptr1 which points the previous node of Ptr. The next pointer of
Ptr1 assigns the address of next pointer of Ptr.
e. Deallocate the Ptr pointer.
Algorithm: - Delete-from-given-position(Start, Pos)
Begin
If Start = NULL Then
Display “List is empty”
Else
Ptr = Start
For i = 1 to Pos – 1 Step 1
Ptr1 = Ptr
Ptr = Ptr [Next]
[End of while statement]
Ptr1 [Next] = Ptr [Next]
Free (Ptr)
[End of if statement]
End
Example – Write a program to create a singly linked list, delete the elements and display
them.
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
struct node
{
int data;
struct node *next;
Page 70
};
typedef struct node node;
node *create(node *, int);
void display(node *);
node *deletefromfirst(node *);
node *deletefromlast(node *);
node *deletefromposition(node *, int);
void main( )
{
int x, ch, p;
node *start = NULL;
clrscr( );
while(1)
{
printf("Enter the number (Type 0 for Exit) - ");
scanf("%d", &x);
if(x = = 0)
break;
start=create(start, x);
}
display(start);
printf("\n 1. Delete from first");
printf("\n 2. Delete from last");
printf("\n 3. Delete from given position");
printf("\n Enter the choice - ");
scanf("%d",&ch);
switch(ch)
{
case 1:
start = deletefromfirst(start);
break;
case 2:
start = deletefromlast(start);
break;
case 3:
printf("Enter the position - ");
scanf("%d", &p);
start = deletefromposition(start, p);
break;
}
display(start);
getch( );
}
node *create(node *start, int val)
{
Page 71
node *temp, *ptr;
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->next = NULL;
if(start = = NULL)
start = temp;
else
{
ptr = start;
while(ptr->next != NULL)
ptr = ptr->next;
ptr->next = temp;
}
return start;
}
void display(node *start)
{
node *ptr = start;
if(start = = NULL)
printf("List is empty");
else
{
while(ptr != NULL)
{
printf("%d -> ", ptr->data);
ptr = ptr->next;
}
}
}
node *deletefromfirst(node *start)
{
node *ptr;
if(start = = NULL)
printf("List is empty");
else
{
ptr = start;
start = start->next;
free(ptr);
}
return start;
}
node *deletefromlast(node *start)
Page 72
{
node *ptr, *ptr1;
if(start = = NULL)
printf("List is empty");
else
{
ptr = start;
while(ptr->next != NULL)
{
ptr1 = ptr;
ptr = ptr->next;
}
ptr1->next = NULL;
free(ptr);
}
return start;
}
node *deletefromposition(node *start, int pos)
{
node *ptr, *ptr1;
int i;
if(start = = NULL)
printf("List is empty");
else
{
ptr = start;
for(i = 1; i < pos; i++)
{
ptr1 = ptr;
ptr = ptr->next;
}
ptr1->next = ptr->next;
free(ptr);
}
return start;
}
Searching a node in linked list: Searching means finding information in the given linked list. For searching an
element, we first traverse the linked list and during traversing, we compare the data part of
each node with the searching element.
Algorithm: - Search(Start, num)
Begin
If Start = NULL Then
Page 73
Display “List is empty”
Else
Loc = 1
Ptr = Start
While Ptr != NULL do
If num = Ptr [Data] Then
Return Loc
[End of if statement]
Ptr = Ptr [Next]
Loc = Loc + 1
[End of while statement]
Return -1
[End of if statement]
End
Example – Write a program to create a singly linked list and search the element in list.
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
struct node
{
int data;
struct node *next;
};
typedef struct node node;
node *create(node *, int);
int search(node *, int);
void main( )
{
int x, s, loc;
node *start = NULL;
clrscr( );
while(1)
{
printf("Enter the number (Type 0 for Exit) - ");
scanf("%d", &x);
if(x = = 0)
break;
start = create(start, x);
}
printf("Enter the number to be searched - ");
scanf("%d", &s);
loc = search(start, s);
if(loc = = -1)
printf("Value not found");
Page 74
else
printf("Value found on position = %d", loc);
getch( );
}
node *create(node *start, int val)
{
node *temp, *ptr;
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->next = NULL;
if(start = = NULL)
start = temp;
else
{
ptr = start;
while(ptr->next != NULL)
ptr = ptr->next;
ptr->next = temp;
}
return start;
}
int search(node *start, int num)
{
node *ptr;
int loc = 1;
if(start = = NULL)
printf("List is empty");
else
{
ptr = start;
while(ptr != NULL)
{
if(num = = ptr->data)
return loc;
ptr = ptr->next;
loc++;
}
return -1;
}
}
Sorting a linked list: Sometimes it is also required to sorting a list in ascending or descending order. In the
sorting operation, first assign a temporary pointer Ptr to Start pointer and then traverse each
node and compare the current node with next node’s data. If the current node’s data is greater
Page 75
than next node’s data then interchange the data values. This process continues till the entire
list will not be sorted.
Algorithm: - Sort(Start)
Begin
If Start = NULL Then
Display “List is empty”
Else
Ptr = Start
While Ptr [Next] != NULL do
Ptr1 = Ptr [Next]
While Ptr1 != NULL do
If Ptr [Data] > Ptr1 [Data] Then
Temp = Ptr [Data]
Ptr [Data] = Ptr1 [Data]
Ptr1 [Data] = Temp
[End of if statement]
Ptr1 = Ptr1 [Next]
[End of while statement]
Ptr = Ptr [Next]
[End of while statement]
[End of if statement]
End
Example – Write a program to sort the elements of singly linked list.
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
struct node
{
int data;
struct node *next;
};
typedef struct node node;
node *create(node *, int);
void display(node *);
node *sort(node *);
void main( )
{
int x;
node *start=NULL;
clrscr( );
while(1)
{
printf("Enter the number (Type 0 for Exit) - ");
Page 76
scanf("%d", &x);
if(x = = 0)
break;
start=create(start, x);
}
printf("\n Before sorting.........\n");
display(start);
start = sort(start);
printf("\n After sorting..........\n");
display(start);
getch( );
}
node *create(node *start, int val)
{
node *temp, *ptr;
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->next = NULL;
if(start = = NULL)
start = temp;
else
{
ptr = start;
while(ptr->next != NULL)
ptr = ptr->next;
ptr->next = temp;
}
return start;
}
void display(node *start)
{
node *ptr = start;
if(start = = NULL)
printf("List is empty");
else
{
while(ptr != NULL)
{
printf("%d -> ", ptr->data);
ptr = ptr->next;
}
}
}
node *sort(node *start)
{
Page 77
node *ptr, *ptr1;
int temp;
if(start = = NULL)
printf("List is empty");
else
{
for(ptr = start; ptr->next != NULL; ptr = ptr->next)
{
for(ptr1 = ptr->next; ptr1 != NULL; ptr1 = ptr1->next)
{
if(ptr->data > ptr1->data)
{
temp = ptr->data;
ptr->data = ptr1->data;
ptr1->data = temp;
}
}
}
}
return start;
}
Merging two linked list: To merge two separate single linked list, firstly traverse the first list till the last node
and then assign the address of first node of the second linked list to the next pointer field of
the last node of first list.
Algorithm: - Merge(Start, Start1)
Begin
Ptr = Start
While Ptr [Next] != NULL do
Ptr = Ptr [Next]
[End of while statement]
Ptr [Next] = Start1
End
Double Linked List: Structure of Double linked list: struct node
{
struct node *prev;
int data;
struct node *next;
};
Creation of a double linked list: To create a double linked list, follow the following steps: Page 78
1.
2.
3.
4.
5.
6.
7.
8.
Create a memory allocation for new TEMP node.
Assign the value to the data part of TEMP node.
Assign the NULL to the next pointer of TEMP node.
Check if the list is empty then assign the NULL into previous pointer of
TEMP node.
Initiate the Start and End pointer to TEMP node.
If list is not empty then assign the address of End pointer to the previous
pointer part of the Temp node.
Assign the address of Temp node to the next pointer of End node.
Set the End pointer on New Temp node.
Algorithm: - Create(Start, val)
Begin
Temp = create a node
Temp [Data] = val
Temp [Next] = NULL
If Start = NULL Then
Temp [Prev] = NULL
Start = End = Temp
Else
Temp [Prev] = End
End [Next] = Temp
End = Temp
[End of if statement]
End
Traversing a double linked list: Traversing of double linked list means accessing each node’s data exactly once.
Traversing may be either in serial or reverse direction. To display the elements of linked list
in serial order, follow the steps: 1. Firstly assign a temporary pointer ‘Ptr’ to ‘Start’ node.
2. Traverse the each node of linked list until the next pointer of ‘Ptr’ has NULL address.
To display the elements of linked list in reverse order, follow the steps: 1. Firstly assign a temporary pointer ‘Ptr’ to ‘End’ node.
2. Traverse the each node of linked list until the previous pointer of ‘Ptr’ has NULL
address.
Algorithm: - Traverse(Start)
Begin
If Start = NULL Then
Display “List is Empty”
Else
Display “In serial order……..”
Ptr = Start
Page 79
While Ptr != NULL do
Display Ptr [Data]
Ptr = Ptr [Next]
[End of while statement]
Display “In reverse order……..”
Ptr = End
While Ptr != NULL do
Display Ptr [Data]
Ptr = Ptr [Prev]
[End of while statement]
[End of if statement]
End
Example – Write a program to create a doubly linked list and display them.
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
struct node
{
int data;
struct node *prev, *next;
};
typedef struct node node;
node *start, *end;
void create(int);
void display( );
void main( )
{
int x;
start = end = NULL;
clrscr( );
while(1)
{
printf("Enter the number (Type 0 for Exit) - ");
scanf("%d", &x);
if(x = = 0)
break;
create(x);
}
display( );
getch( );
}
void create(int val)
{
node *temp;
Page 80
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->next = NULL;
if(start = = NULL)
{
temp->prev = NULL;
start = end = temp;
}
else
{
temp->prev = end;
end->next = temp;
end = temp;
}
}
void display( )
{
node *ptr;
if(start = = NULL)
printf("List is empty");
else
{
printf("\n Display in serial order........\n");
ptr = start;
while(ptr != NULL)
{
printf("%d -> ", ptr->data);
ptr = ptr->next;
}
printf("\n Display in reverse order........\n");
ptr = end;
while(ptr != NULL)
{
printf("%d -> ", ptr->data);
ptr = ptr->prev;
}
}
}
Inserting a node in doubly linked list: The insertion operation is classified into following three categories: 1. Insert at first node
2. Insert at last node
Page 81
3. Insert at given position
1.) Insert at first node: - To insert a node at the beginning of a doubly linked list follow
these steps: a. First create a memory allocation for a new TEMP node.
b. Assign the value to the data part of TEMP node.
c. Assign the NULL to the previous part of TEMP node.
d. Assign the address of START node to the next pointer part of TEMP node.
e. Assign the address of TEMP node to the previous pointer part of START node.
f. Make the new node as the first node in the list by assigning the START on TEMP
node.
Algorithm: - Insert-at-first(val)
Begin
Temp = create a node
Temp [Data] = val
Temp[Prev]=NULL
Temp [Next] = Start
Start[Prev] = Temp
Start = Temp
End
2.) Insert at last node: - To insert a node at the end of a double linked list follow these
steps: a. First create a memory allocation for new TEMP node.
b. Assign the value to the data part of TEMP node.
c. Assign the NULL to the next pointer of TEMP node.
d. Assign the address of END node to the previous pointer of TEMP node.
e. Assign the address of TEMP node to the next pointer of END node.
f. Finally, Set the END pointer to the TEMP node.
Algorithm: - Insert-at-last(val)
Begin
Temp = create a node
Temp [Data] = val
Temp [Next] = NULL
Temp [Prev] = End
End [Next] = Temp
End = Temp
End
3.) Insert at given position: - To insert a node at the specified position of a doubly linked
list follow these steps: a. First create a memory allocation for new TEMP node.
b. Assign the value to the data part of TEMP node.
Page 82
c.
d.
e.
f.
g.
Then obtain the desired position of node by traversing the linked list.
Make the link field of new node to point the next node.
Assign the address of TEMP node into the link part of the previous node.
Assign the address of previous node to the previous pointer of TEMP node.
Assign the address of TEMP node to the previous part of next node and next part
of previous node.
Algorithm: - Insert-at-given-position(val, pos)
Begin
Temp = create a node
Temp [Data] = val
Ptr = Start
For i = 1 to pos – 2 Step 1
Ptr = Ptr [Next]
[End of while statement]
Temp [Next] = Ptr [Next]
Temp [Prev] = Ptr
Ptr [Next] [Prev] = Temp
Ptr [Next] = Temp
End
Example – Write a program to create a singly linked list, insert the elements and display
them.
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
struct node
{
int data;
struct node *prev, *next;
};
typedef struct node node;
node *start, *end;
void create(int);
void display( );
void insertatfirst(int);
void insertatlast(int);
void insertatposition(int, int);
void main( )
{
int x, ch, p;
start = end = NULL;
clrscr( );
while(1)
{
Page 83
printf("Enter the number (Type 0 for Exit) - ");
scanf("%d", &x);
if(x == 0)
break;
create(x);
}
display( );
do
{
printf("\n 1. Insert at first");
printf("\n 2. Insert at last");
printf("\n 3. Insert at given position");
printf("\n Enter the choice - ");
scanf("%d", &ch);
switch(ch)
{
case 1:
printf("Enter the new value - ");
scanf("%d", &x);
insertatfirst(x);
break;
case 2:
printf("Enter the new value - ");
scanf("%d", &x);
insertatlast(x);
break;
case 3:
printf("Enter the new value - ");
scanf("%d", &x);
printf("Enter the position - ");
scanf("%d", &p);
insertatposition(x, p);
break;
}
}while(ch>=1 && ch<=3);
display( );
getch( );
}
void create(int val)
{
node *temp;
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->next = NULL;
if(start = = NULL)
Page 84
{
temp->prev = NULL;
start = end = temp;
}
else
{
temp->prev = end;
end->next = temp;
end = temp;
}
}
void display( )
{
node *ptr;
if(start = = NULL)
printf("List is empty");
else
{
printf("\n Display in serial order........\n");
ptr = start;
while(ptr != NULL)
{
printf("%d -> ", ptr->data);
ptr = ptr->next;
}
printf("\n Display in reverse order........\n");
ptr = end;
while(ptr != NULL)
{
printf("%d -> ", ptr->data);
ptr = ptr->prev;
}
}
}
void insertatfirst(int val)
{
node *temp;
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->next = start;
temp->prev = NULL;
start->prev = temp;
start = temp;
}
Page 85
void insertatlast(int val)
{
node *temp;
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->next = NULL;
temp->prev = end;
end->next = temp;
end = temp;
}
void insertatposition(int val, int pos)
{
node *temp, *ptr = start;
int i;
temp = (node *)malloc(sizeof(node));
temp->data = val;
for(i = 1; i < pos - 1; i++)
ptr = ptr->next;
temp->next = ptr->next;
temp->prev = ptr;
ptr->next->prev = temp;
ptr->next = temp;
}
Deletion in doubly linked list: The deletion operation is classified into following three categories: 1. Delete from first node
2. Delete from last node
3. Delete from given position
1.) Delete from first node: - To delete a node from the beginning of a double linked list
follow these steps: a. Firstly check if the list is empty then give the appropriate message otherwise do
the next steps.
b. Then point a temporary pointer ‘Ptr’ to ‘Start’ node.
c. Move the ‘Start’ pointer to the next node.
d. Assign the NULL to the previous pointer part of current ‘Start’ node.
e. Deallocate the memory of ‘Ptr’ pointer.
Algorithm: - Delete-from-first
Begin
If Start = NULL Then
Display “List is empty”
Else
Page 86
Ptr = Start
Start = Start [Next]
Start [Prev] = NULL
Free (Ptr)
[End of if statement]
End
2.) Delete from last node: - To delete a node from the end of a double linked list follow
these steps: a. Firstly check if the list is empty then give the message otherwise do the next
steps.
b. First point a temporary pointer ‘Ptr’ to End node.
c. Assign the NULL to next pointer of second last node.
d. Deallocate the Ptr pointer.
Algorithm: - Delete-from-last
Begin
If Start = NULL Then
Display “List is empty”
Else
Ptr = End
End = End[Prev]
End [Next] = NULL
Free (Ptr)
[End of if statement]
End
3.) Delete node from the given position: - To delete a node from the given position of a
double linked list follow these steps: a. Firstly check if the list is empty then give the appropriate message otherwise do
the next steps.
b. Then point a temporary pointer ‘Ptr’ to Start node.
c. After that obtain the desired position of node by traversing the linked list.
d. The other pointer Ptr1 which points the previous node of Ptr. The next pointer of
Ptr1 assigns the address of next pointer of Ptr.
e. Assign the address of Ptr1 to the previous pointer of next node.
f. Deallocate the Ptr pointer.
Algorithm: - Delete-from-given-position(Pos)
Begin
If Start = NULL Then
Display “List is empty”
Else
Ptr = Start
For i = 1 to Pos – 1 Step 1
Page 87
Ptr = Ptr [Next]
[End of while statement]
Ptr [Prev][Next] = Ptr [Next]
Ptr [Next][Prev] = Ptr [Prev]
Free (Ptr)
[End of if statement]
End
Single Circular Linked List: A circular linked list is a singly linked list in which the link field of the last node
contains the address of first node of the list, i.e. last node does not contain NULL. With this
type of arrangement, the coupling between each and every elements of the list becomes
cyclic. A circular linked list has no end.
Creation of a single circular linked list: Creation of a circular linked list is same as singly linked list only one thing is vary i.e.
the last node will always point the address of the first node instead of NULL. To create a
circular linked list, follows these steps: 1. Create a new node TEMP by allocating the memory.
2. Assign the value to the data part of TEMP node.
3. Check if START pointer has NULL then it is the first node and assign the address of
TEMP node to the next pointer of TEMP node.
4. If the START pointer has nodes then first traverse the list till last node until the next
pointer of a node does not have the address of START node.
5. Assign the address of TEMP node to the next pointer part of last node and assign the
address of START node to the new TEMP node.
Algorithm: - Create(Start, val)
Begin
Temp = create a node
Temp [Data] = val
If Start = NULL Then
Temp [Next] = Temp
Start = Temp
Else
Ptr=Start
While Ptr [Next] != Start
Ptr = Ptr [Next]
[End of While loop]
Ptr [Next] = Temp
Temp [Next] = Start
[End of if statement]
End
Traversing a linked list: Page 88
Traversing of linked list means accessing each node one by one. Traversing may be
displaying or any other processing of each node’s data. To display the elements of linked list,
follow these steps: 1. Firstly assign a temporary pointer ‘Ptr’ to ‘Start’ node.
2. Traverse the each node of linked list until the ‘Ptr’ has again point to the Start node.
Algorithm: - Traverse(Start)
Begin
If Start = NULL Then
Display “List is Empty”
Else
Ptr = Start
Do
Display Ptr [Data]
Ptr = Ptr [Next]
While (Ptr != Start)
[End of if statement]
End
Inserting a node in single circular linked list: The insertion operation is classified into following three categories: 1. Insert at first node
2. Insert at last node
3. Insert at given position
1.) Insert at first node: - To insert a node at the beginning of a single circular linked list
follow these steps: a. First create a memory allocation for new TEMP node.
b. Assign the value to the data part of TEMP node.
c. Store the address of START node in the link field of new TEMP node.
d. Traverse the list till the last node by using Ptr pointer and then assign the address
of new node to the next pointer of last node.
e. Assign the Start pointer to TEMP node.
Algorithm: - Insert-at-first(Start, val)
Begin
Temp = create a node
Temp [Data] = val
Temp [Next] = Start
Ptr = Start
While Ptr [Next] != Start
Ptr = Ptr [Next]
[End of while statement]
Ptr [Next] = Temp
Start = Temp
Page 89
End
2.) Insert at last node: - To insert a node at the end of a circular linked list follow the
steps: a. First create a memory allocation for new TEMP node.
b. Assign the value to the data part of TEMP node.
c. Assign the temporary pointer Ptr to START node and traverse the list till the end
node.
d. Then assign the address of new node TEMP to the next pointer of last node.
e. Finally, assign the Start address to the next pointer of TEMP node.
Algorithm: - Insert-at-last(Start, val)
Begin
Temp = create a node
Temp [Data] = val
Temp [Next] = Start
Ptr = Start
While Ptr [Next] != Start
Ptr = Ptr [Next]
[End of while statement]
Ptr [Next] = Temp
End
3.) Insert at given position: - To insert a node at the specified position of a circular linked
list follow the steps: a. First create a memory allocation for new TEMP node.
b. Assign the value to the data part of TEMP node.
c. Firstly obtain the desired position of node by traversing the linked list.
d. Make the link field of new node to point the next node.
e. Assign the address of inserted node into the link part of the previous node.
Algorithm: - Insert-at-given-position(Start, val, pos)
Begin
Temp = create a node
Temp [Data] = val
Ptr = Start
For i = 1 to pos – 2 Step 1
Ptr = Ptr [Next]
[End of while statement]
Temp [Next] = Ptr [Next]
Ptr [Next] = Temp
End
Deletion in circular linked list: The deletion operation is classified into following three categories: Page 90
1. Delete from first node
2. Delete from last node
3. Delete from given position
1.) Delete from first node: - To delete a node from the beginning of a circular linked list
follow these steps: a. Firstly check if the list is empty then display the appropriate message otherwise do
the next steps.
b. First point a temporary pointer Ptr to Start node.
c. Assign another pointer ‘Ptr1’ to Start node and traverse till the end node.
d. Assign the next pointer of Start address to the Start.
e. Assign the address of second node to the next pointer of Ptr1.
f. Deallocate the Ptr pointer.
Algorithm: - Delete-from-first(Start)
Begin
If Start = NULL Then
Display “List is empty”
Else
Ptr = Ptr1 = Start
While Ptr1 [Next] != Start
Ptr1 = Ptr1 [Next]
[End of while statement]
Start = Start [Next]
Ptr1 [Next] = Start
Free (Ptr)
[End of if statement]
End
2.) Delete from last node: - To delete a node from the end of a circular linked list follow
these steps: a. Firstly check if the list is empty then display the appropriate message otherwise do
the next steps.
b. First point a temporary pointer ‘Ptr’ to Start node.
c. Traverse the linked list till the last node and take another pointer Ptr1 which points
to the previous node of the current node ‘Ptr’.
d. After that assign the address of Start node to the next pointer of node ‘Ptr1’.
e. Deallocate the Ptr pointer.
Algorithm: - Delete-from-last(Start)
Begin
If Start = NULL Then
Display “List is empty”
Else
Ptr = Start
While Ptr [Next] != Start
Page 91
Ptr1 = Ptr
Ptr = Ptr [Next]
[End of while statement]
Ptr1 [Next] = Start
Free (Ptr)
[End of if statement]
End
3.) Delete node from the given position: - To delete a node from the given position of a
linked list follow these steps: a. Firstly check if the list is empty then give the message otherwise do the next steps.
b. First point a temporary pointer ‘Ptr’ to Start node.
c. Firstly obtain the desired position of node by traversing the linked list.
d. The other pointer Ptr1 which points the previous node of Ptr. The next pointer of
Ptr1 assigns the address of next pointer of Ptr.
e. Deallocate the Ptr pointer.
Algorithm: - Delete-from-given-position(Start, Pos)
Begin
If Start = NULL Then
Display “List is empty”
Else
Ptr = Start
For I = 1 to Pos – 1 Step 1
Ptr1 = Ptr
Ptr = Ptr [Next]
[End of while statement]
Ptr1 [Next] = Ptr [Next]
Free (Ptr)
[End of if statement]
End
Advantages of Circular Linked list: 1. Cyclic traversal of a linked list can be possible at a very high speed especially when
we are working with a very large database.
2. No extra memory is required to implement a circular linked list.
Sorted Singly Linked list: In case of creation of sorted linked list when we add the elements in the linked list
then it should be inserted at the proper place. If the list is empty then directly assign the first
node to START pointer, but if the value is less than the value of first node then add at
beginning or if greater then either it is lies between or at the end of list.
Algorithm: - Create(Start, val)
Begin
Temp = Create a node
Page 92
Temp [Data] = val
If Start = NULL Then
Temp [Next] = NULL
Start = Temp
Else If val < Start [Data] Then
Temp [Next] = Start
Start = Temp
Else
Ptr = Start
While Ptr [Next] != NULL And Ptr [Next][Data] < val
Ptr = Ptr [Next]
[End of while statement]
Temp [Next] = Ptr [Next]
Ptr [Next] = Temp
[End of if statement]
End
Example – Write a program to create a sorted linked list and display them.
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
struct node
{
int data;
struct node *next;
};
typedef struct node node;
node *create(node *, int);
void display(node *);
void main( )
{
int x;
node *start=NULL;
clrscr( );
while(1)
{
printf("Enter the number (Type 0 for Exit) - ");
scanf("%d", &x);
if(x = = 0)
break;
start = create(start, x);
}
display(start);
getch( );
}
Page 93
node *create(node *start, int val)
{
node *temp, *ptr;
temp = (node *)malloc(sizeof(node));
temp->data = val;
if(start = = NULL)
{
temp->next = NULL;
start = temp;
}
else if(val < start->data)
{
temp->next = start;
start = temp;
}
else
{
ptr = start;
while(ptr->next != NULL && ptr->next->data < val)
ptr = ptr->next;
temp->next = ptr->next;
ptr->next = temp;
}
return start;
}
void display(node *start)
{
node *ptr = start;
if(start = = NULL)
printf("List is empty");
else
{
while(ptr != NULL)
{
printf("%d -> ", ptr->data);
ptr = ptr->next;
}
}
}
Header Linked List: A header linked list always contains a special node, called the header node, at the
beginning of the list. This type of list is useful when information other than that found in each
node is needed. E.g. – suppose there is an application in which the number of items in a list is
Page 94
often calculated. Usually a list is always traversed to find the length of the list. However, if
the current length is maintained in an additional header node, that information can be easily
obtained.
There are two kinds of widely used header lists: 1. Grounded Header Linked list
2. Circular Header Linked list
1.) Grounded Header Linked list: It is a header list where the last node contains NULL pointer. In the header
linked list the ‘Start’ pointer always points to the header node. Next pointer of Start
assigns NULL indicates that a grounded header linked list is empty. The operations
that are possible on this type of linked list are:  Insertion
 Deletion
 Traversing
Creating the grounded header linked list: Algorithm: - Create(Start, val, Count)
Begin
Temp = Create a node
Temp [Data] = val
Temp [Next] = NULL
If Count = 0 Then
Start [Next] = Temp
Count = Count + 1
Start [Data] = Count
Else
Ptr = Start [Next]
While Ptr [Next] != NULL
Ptr = Ptr [Next]
[End of while statement]
Ptr [Next] = Temp
Count = Count + 1
Start [Data] = Count
[End of if statement]
End
Traversing grounded header linked list: Algorithm: - Traverse(Start)
Begin
If Start = NULL Then
Display “List is empty”
Else
Page 95
Ptr = Start
Count = Ptr [Data]
Ptr = Ptr [Next]
While Count != 0
Display Ptr [Data]
Ptr = Ptr [Next]
Count = Count – 1
[End of while statement]
[End of if statement]
End
2.) Circular Header Linked list: It is a header linked list where the last node points back to the header node.
The chains do not indicate first or last nodes. In this case, external pointers provide a
frame of reference because last node of a circular linked list does not contain the
NULL pointer. The possible operations on this type of linked list are:  Insertion
 Deletion
 Traversing
Creating the circular header linked list: Algorithm: - Create(Start, val, Count)
Begin
Temp = Create a node
Temp [Data] = val
Temp [Next] = Start
If Count = 0 Then
Start [Next] = Temp
Count = Count + 1
Start [Data] = Count
Else
Ptr = Start [Next]
While Ptr [Next] != Start
Ptr = Ptr [Next]
[End of while statement]
Ptr [Next] = Temp
Count = Count + 1
Start [Data] = Count
[End of if statement]
End
Traversing circular header linked list: Algorithm: - Traverse(Start)
Page 96
Begin
If Start = NULL Then
Display “List is empty”
Else
Ptr = Start
Count = Ptr [Data]
Ptr = Ptr [Next]
While Ptr != Start
Display Ptr [Data]
Ptr = Ptr [Next]
Count = Count – 1
[End of while statement]
[End of if statement]
End
Page 97
Unit - III
Trees: Trees are the most important data structures in computer science. Trees are used to
represent data containing a hierarchical relationship between parent and their child.
A tree is a non-linear data structure in which data elements are arranged in a sorted
sequence. A tree can be defined as a finite set of one or more nodes such that: 1. There is a specially designed node called the root.
2. The remaining nodes are partitioned into number of disjoint set T1, T2, …….., Tn
where each of these sets is a tree T1, T2, …….., Tn, are called the subtrees of the
root.
Tree Terminology: 1. Root: - It is specially designed data item in a tree. The root of tree is the origin of tree
from where the tree starts.
2. Node: - Each data item in a tree called a node. A node holds the item of information
and branches to other nodes.
3. Degree of node: - The number of subtrees of a node is called its degree.
4. Degree of a tree: - Degree of a tree is the total number of subtrees or number of levels
in a tree. The degree of above tree is 3.
5. Leaf node or Terminal node or External node: - A node that has no child is called leaf
node or a node that has degree 0 is called leaf or terminal or external node. In the
above figure D, H, E, F and G are leaf nodes.
6. Non-leaf or non-terminal or internal node: - Any node whose degree is not 0 except
the root node is called the non-leaf, non-terminal or internal node. In the above figure
B and C are internal nodes.
7. Siblings: - The children nodes of the same parent are said to be siblings. In the above
figure H and E are the siblings of D node.
8. Edges: - It is connecting line down from one node to another node.
9. Path: - It is a sequence of consecutive edges from the source node to the destination
node. In the above figure, the path between A and E is given by the nodes pairs (A, B)
& (B, E).
10. Levels: - Each node in a tree is assigned a level number. The root node of the tree is
assigned a level number 0 then its children at level 1 and their childrens are at level 2
and so on up to the terminal nodes.
11. Branch: - A path ending on a leaf node is called branch.
12. Depth: - Depth or height of a tree is the maximum number of nodes in a branch of tree
i.e. one more than the largest level number of tree.
Page 98
13. Forest: - It is a set of disjoint trees. In a given tree, if we remove its root node then it
becomes a forest.
14. Predecessor or Ancestor: - A node is called ancestor of another node, if it is parent of
that node. In the above figue, node A is ancestor of nodes B and C.
15. Successor or Descendant: - A node is called successor of another node, if it is child of
that node. In the above figure, B and C are successor of node A.
Binary Tree: A tree is a binary tree if each node of it can have at most two childrens or branches. A
binary tree ‘T’ is a finite set of nodes which is either empty (called empty or null tree) or
consists of special node called root ‘R’ of the tree ‘T’ and two disjoint binary tree ‘T1’ and
‘T2’ which are called left subtrees and right subtrees.
In binary tree, the maximum degree of any node is at most two. That means, there
may be a zero degree node or one degree node and two degree node.
Strictly Binary Tree: If every non terminal node in a binary tree consists of non empty left subtrees and
right subtrees, then such a tree is called strictly binary tree.
Complete Binary Tree: A complete binary tree is called a binary tree if each node of a tree have either exactly
two children or no child at all, and all of leaves are at same level. A complete binary tree at
the level L can have 2L nodes.
E.g. –
If L = 0, then 20 = 1 i.e. 1 node that is a root.
If L = 1, then 21 = 2 i.e. 2 nodes at level 1.
If L = 2, then 22 = 4 i.e. 4 nodes at level 2 and so on.
Page 99
Full Binary Tree: A binary tree in which all the leaf nodes are on the same level and every non leaf node
has two children is called full binary tree. A full binary tree must have 2L node at each level
L.
Extended Binary Tree or 2-Tree: A binary tree is called extended binary tree if each node has either 0 or 2 children.
Nodes with 2 children are called ‘internal node’ and the nodes, which have no children, are
called ‘external nodes’.
Skewed Tree: A skewed tree is a binary tree that is skewed to either left side or right side.
Left Skewed Tree
Right Skewed Tree
Similar Tree and Equivalent Tree: The binary tree T and T’ are similar if they have same structures or if they have same
shape but with different values is called similar tree.
The tree are said to be equivalent or copies if they are similar and they have same
contents at the corresponding nodes.
Representation of a binary tree: There are following two ways to implement a binary tree: 1. Sequential or Array representation
2. Linked list representation
Page 100
1.) Sequential or Array representation: If a binary tree is complete or nearly complete binary tree can be efficiently
represented by sequential representation. This representation uses a one dimensional
array. An array can be used to store the nodes of binary tree. It requires the numbering
of nodes. In array, the root node is always numbered by 0 and then its left child and
right child are stored at 1 and 2 respectively.
The array representation of this binary tree is as follows: A
0
B
1
C
2
3
4
D
5
E
6
7
8
9
10
F
11
G
12
13
14
2.) Linked list representation: The array representation is good for complete binary tree, but it is wasteful for
many other binary trees like skewed tree. In array representation, the insertion and
deletion of nodes from the middle of a tree requires the movement of many nodes.
This problem can be overcome easily through the use of a linked list representation.
Basic component in a binary tree is a node. Each node has three fields, one for
the link of left child, second for the data and third for the link of right child. Left child
contains the address of its left node and right child contains the address of its right
node.
Left Child Data Right Child
The representation of a node in C is: struct node
{
struct node *leftchild;
int data;
struct node *rightchild;
};
typedef struct node node;
Page 101
Operations on Binary Tree: 1. Creation of Binary Tree
2. Traversal of Binary Tree
3. Insertion of Nodes
4. Deletion of Nodes
5. Searching for the Nodes
Creation of Binary Tree: Algorithm – Create_Tree(T, val)
Where val is element for which we have to create node and T is structure type
variable to points both left and right child.
Begin
If T = NULL Then
T = create a node
T [Data] = val
T [Left_child] = NULL
T [Right_child] = NULL
Else if T [Data] >= val Then
T [Left_child] = Call Create_Tree(T[Left_child], val)
Else
T [Right_child] = Call Create_Tree(T[Right_child], val)
[End of if statement]
Return (T)
End
Traversal of a Binary Tree: Traversing is a way in which each node in the binary tree is visited exactly once.
There are three standard ways of a binary tree traversal. These methods are known as: 1. Inorder Traversal
2. Preorder Traversal
3. Postorder Traversal
The tree traversal methods are written either in recursive or non recursive algorithm.
1.) Preorder Traversal: To traverse a non empty binary tree in preorder, we perform the following
operations: a. Process the root
b. Traverse the left subtrees
c. Traverse the right subtrees
Algorithm – Preorder(T)
Begin
If T != NULL Then
Display T [Data]
Call Preorder(T [Left_child])
Page 102
Call Preorder(T [Right_child])
[End of if statement]
End
2.) Inorder Traversal: To traverse a non empty binary tree in inorder, we perform the following
operations: a. Traverse the left subtrees
b. Process the root
c. Traverse the right subtrees
Algorithm – Inorder(T)
Begin
If T != NULL Then
Call Inorder(T [Left_child])
Display T [Data]
Call Inorder(T [Right_child])
[End of if statement]
End
3.) Postorder Traversal: To traverse a non empty binary tree in postorder, we perform the following
operations: a. Traverse the left subtrees
b. Traverse the right subtrees
c. Process the root
Algorithm – Postorder(T)
Begin
If T != NULL Then
Call Postorder(T [Left_child])
Call Postorder(T [Right_child])
Display T [Data]
[End of if statement]
End
Example – Write a program to create a binary tree using recursive algorithm and traverse it.
#include<stdio.h>
#include<conio.h>
struct node
{
int data;
struct node *left_child, *right_child;
};
typedef struct node node;
Page 103
node *create_tree(node *, int);
void preorder(node *);
void inorder(node *);
void postorder(node *);
void main( )
{
int x;
node *T = NULL;
clrscr( );
while(1)
{
printf("Enter the number (type 0 for exit) - ");
scanf("%d",&x);
if(x = = 0)
break;
T = create_tree(T, x);
}
printf("\n Preorder Traversal.....");
preorder(T);
printf("\n Inorder Traversal.....");
inorder(T);
printf("\n Postorder Traversal.....");
postorder(T);
getch( );
}
node *create_tree(node *T, int val)
{
if(T == NULL)
{
T = (node *)malloc(sizeof(node));
T->data = val;
T->left_child = NULL;
T->right_child = NULL;
}
else if(T->data >= val)
T->left_child = create_tree(T->left_child, val);
else
T->right_child = create_tree(T->right_child, val);
return T;
}
void preorder(node *T)
{
if(T != NULL)
{
printf("\n %d", T->data);
Page 104
preorder(T->left_child);
preorder(T->right_child);
}
}
void inorder(node *T)
{
if(T != NULL)
{
inorder(T->left_child);
printf("\n %d", T->data);
inorder(T->right_child);
}
}
void postorder(node *T)
{
if(T != NULL)
{
postorder(T->left_child);
postorder(T->right_child);
printf("\n %d", T->data);
}
}
BST (Binary Search Tree)
A binary tree in which all elements in the left subtrees of a node ‘N’ are less than the
node element and all elements in the right subtrees of node ‘N’ are greater than the node
element is called Binary search tree (BST).
1. If the BST is traversed in inorder, then the contents of each node are printed in
ascending order.
2. In BST, we can search for an element easily with an average running time f(n) =
O(log2n)
Searching a value in Binary Search Tree: Searching is used to find whether the data is present or not in the tree. To search a
particular node in binary search tree, follow these steps: 1. To search any node in a BST, initially the data is compared with the data of the root
node. If the data is matched then searching is successful.
2. If the searching is found to be greater than the data of the root node then we will move
for searching in the right subtree of the root node, otherwise we will move for
searching in left subtree of root node.
3. This procedure is repeated until the data is found.
4. If the leaf node is reached and data is not found then it is concluded that the data is
not present in the tree.
Page 105
Algorithm: - search(T, val)
Begin
If T = NULL Then
Display "Tree is empty"
Else
ptr = T
While ptr != NULL do
If val < ptr [Data] Then
ptr = ptr [Left]
Else if val > ptr [Data] Then
ptr = ptr [Right]
Else
return 1
[End of if statement]
[End of while statement]
Return 0
[End of if statement]
End
Insertion of a node in Binary Search Tree: To insert a data in BST, we need to find out the position of the data where it exactly
fits into the tree so that the tree remains binary search tree. To insert any node into BST,
initially the data that is to be inserted is compared with the data of the root node. If the data is
found to be greater than the data of root node then the new node is inserted in right subtree of
the root node. Otherwise, the node is inserted in the left subtree of the root node. This
procedure is repeated for the left subtrees and right subtrees. This is done till the left or right
subtree where the new node is to be inserted is found to be empty. Finally the new node is
made the appropriate child of the current node.
Algorithm: - insert(T, val)
Begin
Temp = create a node
Temp [Data] = val
Temp [Left] = NULL
Temp [Right] = NULL
If T = NULL Then
T = Temp
Else
ptr = T
While ptr != NULL do
ptr1 = ptr
If val < ptr [Data] Then
ptr = ptr [Left]
Else if val > ptr [Data] Then
ptr = ptr [Right]
Page 106
Else
Display "Duplicate values are not allowed"
return T
[End of if statement]
[End of while statement]
If val < ptr1 [Data] Then
ptr1 [Left] = Temp
Else
ptr1 [Right] = Temp
[End of if statement]
[End of if statement]
Return T
End
Example – Write a program to insert nodes in BST and traverse it.
#include<stdio.h>
#include<conio.h>
struct node
{
int data;
struct node *left,*right;
};
typedef struct node node;
node *insert(node *, int);
void preorder(node *);
void inorder(node *);
void postorder(node *);
void main( )
{
int x;
node *T = NULL;
clrscr( );
while(1)
{
printf("Enter the number (type 0 for exit) - ");
scanf("%d",&x);
if(x = = 0)
break;
T = insert(T, x);
}
printf("\n Preorder Traversal.....");
preorder(T);
printf("\n Inorder Traversal.....");
inorder(T);
printf("\n Postorder Traversal.....");
Page 107
postorder(T);
getch( );
}
node *insert(node *T, int val)
{
node *temp, *ptr, *ptr1;
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->left = temp->right = NULL;
if(T = = NULL)
T = temp;
else
{
ptr = T;
while(ptr != NULL)
{
ptr1 = ptr;
if(val < ptr->data)
ptr = ptr->left;
else if(val > ptr->data)
ptr = ptr->right;
else
{
printf("Duplicate values are not allowed");
return T;
}
}
if(val < ptr1->data)
ptr1->left = temp;
else
ptr1->right = temp;
}
return T;
}
void preorder(node *T)
{
if(T != NULL)
{
printf("\n %d", T->data);
preorder(T->left);
preorder(T->right);
}
}
Page 108
void inorder(node *T)
{
if(T != NULL)
{
inorder(T->left);
printf("\n %d", T->data);
inorder(T->right);
}
}
void postorder(node *T)
{
if(T != NULL)
{
postorder(T->left);
postorder(T->right);
printf("\n %d", T->data);
}
}
Example – Write a program to create a BST and search the element is BST.
#include<stdio.h>
#include<conio.h>
struct node
{
int data;
struct node *left,*right;
};
typedef struct node node;
node *insert(node *, int);
int search(node *, int);
void main( )
{
int x, s;
node *T = NULL;
clrscr( );
while(1)
{
printf("Enter the number (type 0 for exit) - ");
scanf("%d",&x);
if(x = = 0)
break;
T = insert(T, x);
}
printf("\n Enter the number to be searched - ");
Page 109
scanf("%d", &s);
if(search(T, s) = = 1)
printf("Value found");
else
printf("Value not found");
getch( );
}
node *insert(node *T, int val)
{
node *temp, *ptr, *ptr1;
temp = (node *)malloc(sizeof(node));
temp->data = val;
temp->left = temp->right = NULL;
if(T = = NULL)
T = temp;
else
{
ptr = T;
while(ptr != NULL)
{
ptr1 = ptr;
if(val < ptr->data)
ptr = ptr->left;
else if(val > ptr->data)
ptr = ptr->right;
else
{
printf("Duplicate values are not allowed");
return T;
}
}
if(val < ptr1->data)
ptr1->left = temp;
else
ptr1->right = temp;
}
return T;
}
int search(node *T, int val)
{
node *ptr;
if(T = = NULL)
printf("Tree is empty");
else
Page 110
{
ptr = T;
while(ptr != NULL)
{
if (val < ptr->data)
ptr = ptr->left;
else if (val > ptr->data)
ptr = ptr->right;
else
return 1;
}
return 0;
}
}
Deletion of a node in Binary Search Tree: Before deleting a node, first we find the location of node ‘Ptr’ which contains the
required data and also the location of parent node. Deletion of a node from the binary search
tree depends on the number of children of node ‘Ptr’. There are following four cases: Case 1: If the node Ptr to be deleted has no child: In this case, node ‘Ptr’ is deleted from the tree by simply replacing the location of
node in the parent node by the NULL pointer.
Algorithm – Deletion of a node in BST
Ptr points the current node and Ptr1 points to the parent node.
Begin
If Ptr [Left] = NULL And Ptr [Right] = NULL Then
If Ptr1 [Right] = Ptr Then
Ptr1 [Right] = NULL
Else
Ptr1 [Left] = NULL
[End of if statement]
Free (Ptr)
[End of if statement]
End
Case 2: If the node Ptr to be deleted has only right child: In this case, node ‘Ptr’ is deleted from the tree by simply replacing the location of
deleted node ‘Ptr’ in the parent node by the location of the child of deleted node ‘Ptr’.
Algorithm – Deletion of a node in BST
Ptr points the current node and Ptr1 points to the parent node.
Begin
If Ptr [Left] = NULL And Ptr [Right] != NULL Then
If Ptr1 [Left] = Ptr Then
Page 111
Ptr1 [Left] = Ptr [Right]
Else
Ptr1 [Right] = Ptr [Right]
[End of if statement]
Free (Ptr)
[End of if statement]
End
Case 3: If the node Ptr to be deleted has only left child: In this case, node ‘Ptr’ is deleted from the tree by simply replacing the location of
deleted node ‘Ptr’ in the parent node by the location of the child of deleted node ‘Ptr’.
Algorithm – Deletion of a node in BST
Ptr points the current node and Ptr1 points to the parent node.
Begin
If Ptr [Left] != NULL And Ptr [Right] = NULL Then
If Ptr1 [Left] = Ptr Then
Ptr1 [Left] = Ptr [Left]
Else
Ptr1 [Right] = Ptr [Left]
[End of if statement]
Free (Ptr)
[End of if statement]
End
Case 4: If the node Ptr to be deleted has two children: When a node Ptr is deleted, we replace node Ptr by left most child of its right subtree.
Algorithm – Deletion of a node in BST
Ptr points the current node and Ptr1 points to the parent node.
Begin
If Ptr [Left] != NULL And Ptr [Right] != NULL Then
Ptr1 = Ptr
PtrSucc = Ptr [Right]
While PtrSucc [Left] != NULL
Ptr1 = PtrSucc
PtrSucc = PtrSucc [Left]
[End of while statement]
Ptr [Data] = PtrSucc [Data]
Ptr = PtrSucc
[End of if statement]
End
Threaded Binary Tree: Generally the pointer fields LEFT and RIGHT will contain NULL elements. This
space may be more efficiently used by replacing the null entries by some other type of
Page 112
information. We will replace the null entries by special pointers with which point to nodes
higher in the tree. These special pointers are called threads, and the binary trees with such
pointers are called threaded trees.
An extra 1-bit TAG field may be used to differentiate threads from ordinary pointers
or threads may be denoted by negative integers when ordinary pointers are denoted by
positive integers.
There are two ways to thread a binary tree: 1. One way or Right threading
2. Two way or Left threading
3. Full threading
One way or right threading of tree: In one way threading of tree, a thread will appear in right field of the node and will
point to the next node in the inorder traversal of tree.
Two way or left threading of tree: In two way threaded binary trees, a thread will appear in left field of a node and will
point to the preceding node in the inorder traversal of tree.
Full threaded tree: In full threaded binary tree, two threads will appear in both left and right field of a
node and will point to the preceding and next node in the tree.
Height Balanced Tree: A tree is perfectly height balanced if the left and right subtrees of any node are at the
same height.
AVL Tree: In 1962, the Russian mathematicians G.M. Adelson, Velskii and E.M. Landis gave a
technique to balance the height of a binary tree, then the resulting tree is called AVL tree. In
other words, AVL tree is a binary search tree in which the height of the left and right subtrees
of each node will be with maximum difference 1.
With the help of AVL trees; searching, insertions and deletions in a tree with node n
is achieved in time of order O(n), even in the worst case.
It is clear that at each level, there are twice as many nodes at the previous level.
However, a perfect height balanced tree is very rare. It is only possible if there are exactly 2 L
– 1 node at level L. The difference of each node is in the range of -1, 0 and +1.
Page 113
Computing height of a Binary tree: For the height balanced, we calculate the balance factor (B.F.) of each node. The
balance factor of each node should lies in the range of -1, 0, and +1. If the balance factor of
any node of a tree is not in this range, then that tree is not height balanced. Balance factor
may be defined as: B.F. = Height of left subtree – Height of right subtree
Example – To construct an AVL tree, consider the following data to be inserted in AVL tree:
25, 45, 50, 55, 60, 65, 75
Solution –
1. Start from the first node 25.
2. Insert 45, node 45 is greater than 25, so it will add right side of 25. Find B.F. of every
node and check whether every node is balanced or not.
3. Insert 50, since 50 > 45, it will add right child of node 45. Now find the B.F. of every
node.
4. Insert 55 in the right side of 50. Now find B.F. of every node.
Page 114
5. Insert 60 in the right side of 55. Now find B.F. of every node.
After balancing the critical node –
6. Insert 65 in the right side of 60. Now find B.F. of every node.
After balancing the critical node –
7. Insert 75 in the right side of 65. Now find B.F. of every node.
Page 115
After balancing the critical node –
B – Tree: In BST, so many nodes have left subtree but no right subtree. Similarly they have
right subtree but no left subtree. Insertion of key also increases the height of tree. When the
height of tree increases, then the access time in tree is totally increases on level of tree. So if
we want to minimize the access time which can be through balanced tree only. So we have a
need to take all there leaf nodes at same level and non leaf nodes should not contain the
empty subtree.
A B-tree is a balanced M-way tree. B-tree or order M has the following properties: 1. It should be perfectly balanced i.e. every leaf node is at the same level.
2. Each node except the root contains minimum M/2 children and maximum M children.
3. Each node has one fewer value than children. No node can contain more than M – 1
values.
4. Keys are arranged in a defined order within the node.
5. When a new key is to be inserted into a full node, this is split into two nodes, and the
key with the median value is inserted in the parent node. In case the parent node is the
root, a new root is created.
Page 116
UNIT – IV
Graphs: A graph G consists of two sets V and E where V is a finite set of vertices or nodes and
E is a set of edges. Thus a graph is defined as a collection of vertices and edges and it is
represented by G = (V, E). An edge is defined as a pair of vertices, which are adjacent to each
other.
It shows a Simple graph, for which –
V(G) = {A, B, C}
E(G) = {e1, e2, e3}
Where V(G) is a set of vertices and E(G) is a set of edges. There are three vertices and three
edges in the graph. The edge e1 is incident with node A and node B.
e1 = (A, B) or (B, A)
e2 = (A, C) or (C, A)
e3 = (C, B) or (B, C)
then E(G) = {(A, B), (A, C), (B, C)}
Graph terminology: 1. Directed Edge: An edge that is directed from one vertex to another is called a directed edge.
2. Undirected Edge: An edge which has no specific direction is called a undirected edge.
3. Directed Graph: A graph in which every edge is directed is called a directed graph or diagraph.
V = {A, B, C, D}
Page 117
E = {e1, e2, e3, e4, e5}
e1 = {A, B}
e2 = {C, A}
e3 = {C, D}
e4 = {D, B}
e5 = {A, D}
4. Undirected Graph: A graph in which every edge is undirected is called a undirected graph.
e1 = {A, B} or {B, A}
e2 = {C, A} or {A, C}
e3 = {C, D} or {D, C}
e4 = {D, B} or {B, D}
e5 = {A, D} or {D, A}
5. Mixed Graph: If some of the edges are directed and some are undirected graph, then the
graph is called mixed graph.
6. Multi Graph: When two or more edges are used to join vertices, such edges are called
parallel edges and the graph is called multi graph.
7. Simple Graph: If there is only one edge between a pair of vertices, then such graph is called
simple gaph.
8. Null Graph: A graph without any edge is called Null graph.
Page 118
9. Isolated Vertex: When a node which is not adjacent to any other node in the graph is called an
isolated vertex.
10. Path: A path is a sequence of consecutive edges from the source node to destination
node.
11. Cycle: A cycle is a path in which the first and last vertices are same.
12. Loop: An edge will be called self loop or self edge if it starts and ends on the same
node.
13. Cyclic Graph: If a graph contains loop or cycles it is called cyclic graph.
14. Connected Graph: An undirected graph is called connected, if there exist a path fron any vertex
to any other vertex.
15. Complete Graph: A graph is said to be complete or fully connected if every node is connected to
every other node in a graph. An undirected complete graph with n nodes will
have n(n – 1) / 2 edges.
16. Weighted or Network Graph: Number associated with an edge is called its weight or value. A graph with
edge value is called weighted graph.
17. Indegree: The indegree of the vertex in directed graph is the number of edges ending at
it.
18. Outdegree: The indegree of the vertex in directed graph is the number of edges starting
from it.
19. Acyclic Graph: A graph that has no cycles is called acyclic graph. When the direction exists in
acyclic graph is called DAG (Directed Acyclic Graph).
20. Maximum edges in Graph: In an undirected graph, there can be n(n – 1) / 2 maximum edges and in a
directed graph, there can be n (n – 1) maximum edges, where n is the total number of
vertices in the graph.
21. Weakly Connected: -
Page 119
A directed graph is called weakly connected if for any pair of vertices u and v
there is not a path from u to v and v to u.
22. Strongly Connected: A directed graph is called strongly connected if there is a path from any vertex
to any other vertex in a graph.
23. Total Degree of vertex: It is the sum of outdegree and indegree of the vertex or the number of edges
incident on the vertex determine its degree. In case of undirected graph, total degree
of the vertex v is the equal to the number of edges incident with v.
24. Tree: A graph is a tree it has two properties: (i)
It is connected
(ii)
There are no cycles in the graph.
25. Source: A node which has no incoming edges but has outgoing edges is called source
vertex. The indegree of source is 0.
26. Sink: A node which has no outgoing edges but has incoming edges is called sink
vertex. The outdegree of sink is 0.
Graph Representation: There are two popular ways to represent a graph in computer’s memory: 1. Sequential Representation
2. Linked Representation
Sequential Representation: In sequential representation, graph can be represented as matrices. An adjacency
matrix is the most common matrix to represent a graph.
Adjacency Matrix: Adjacency matrix is the matrix, which keeps the information of adjacent vertices.
Suppose there are 5 vertices in graph, then row 1 represents the vertex 1, row 2 represents the
vertex 2 and so on. Similarly column 1 represents the vertex 1, column 2 represents the vertex
2 and so on. It is a sequence matrix having one row and one column for each vertex. The
element of adjacency matrix is either 1 or 0. A value 1 for row i and column j implies that an
edge (eij) exists between Vi and Vj. A value 0 means there is no edge between vertex Vi and
Vj.
The adjacency matrix A for a graph G = (V, E) with n vertices is an n * n matrix such
that,
1
if there is an edge between Vi and Vj
0
if there is no edge
Aij =
Note – A matrix which contains 1 or 0 is called a Bit matrix or a Boolean matrix.
Page 120
Example –
Adjacency Matrix Representation of Directed graph
A
B
C
D
E
A
0
1
0
1
0
B
0
0
1
0
1
C
1
0
0
0
0
D
0
0
1
0
1
E
0
0
0
0
0
Note: 1. From the adjacency matrix, it is clear that number of 1’s is equal to the number of
edges in the graph.
2. The number in each row shows the outdegree of vertex.
3. If graph is undirected, the adjacency matrix will be symmetric i.e. rows and columns
value are equal.
4. For a NULL graph, adjacency matrix has all of its elements 0.
5. If there are loops at each vertex but no edges in the graph, then the adjacency matrix
will be unit matrix.
6. For a weighted graph, the elements of adjacency matrix are the weight on that edge.
Incidence Matrix: The incidence matrix contains the row for every vertex and a column for every edge.
The values of the matrix are -1, 0 or 1. If the kth edge is (Vi, Vj), the kth column has the value
1 in the ith row, -1 in the jth row and 0 elsewhere.
Linked list Representation: It is also called Adjacency List Representation. If the adjacency matrix of the graph is
sparse then it is more efficient to represent the graph through adjacency list. For adjacency
list representation, we maintain a list for each vertex and then for each vertex, we have a
linked list of its adjacent vertices.
Page 121
In actual vertices are represented by node with 3 parts, one data and 2 links parts. The
data part represents vertex, one link part represents next vertex and other link part represents
edges of graph.
Example –
Graph Traversal: A graph traversal means visiting all the nodes of the graph. There are two standard
ways for traversing a graph: 1. Breadth First Search (BFS)
2. Depth First Search (DFS)
Breadth First Search (BFS): The BFS uses a queue as an auxiliary structure to store the nodes for future
processing. In a BFS, we will require the starting vertex from which this search will begin.
First one vertex is selected as the start position, it is visited and printed, and then all unvisited
vertices, adjacent to it are visited and printed in some sequential order. Finally, the unvisited
vertices immediately adjacent to these vertices are visited and printed and so on, until the
entire graph has been traversed. There are 3 states of nodes in BFS: 1. Ready state: - When a node is not visited at all, means it did not reaches to queue.
2. Waiting state: - When a node is inserted to queue and is to be processed later on.
3. Processed state: - When a node is removed from queue and processed, than it is said
to be in processed state.
Algorithm – Breadth First Search
Step 1 –
Begin
Step 2 –
[Initializing all nodes to the ready state] STATUS = 1
Step 3 –
Put the starting node A in QUEUE and change its status to the waiting
state (STATUS = 2).
Step 4 –
Repeat step 5 and 6 until QUEUE is empty
Step 5 –
Remove the front node N of QUEUE. Process N and change the status
of N to the processed state (STATUS = 3).
Step 6 –
add the rear of queue all the neighbors of N that are in ready state
(STATUS = 1) and change their status to the waiting state (STATUS =
2)
Step 7 –
End
Page 122
Depth First Search (DFS): In BFS, the traversal of graph proceeds level by level. But DFS
traversal follows first a path from a starting node to an ending node. Then another path from
the start to the end and so on until all nodes has been visited. Here we need stack instead of
queue. The nodes which are either traversed or already available in the stack are not pushed.
We already know that an element is pushed or popped at the top of the stack. There are 3
states of nodes in DFS: 1. Ready state: - When a node is not pushed to stack.
2. Waiting state: - When a node is pushed to stack, but not popped.
3. Processed state: - When a node is popped from stack.
Algorithm – Depth First Search
Step 1 –
Begin
Step 2 –
[Initializing all nodes to the ready state] STATUS = 1
Step 3 –
Push the starting node A in STACK and change its status to the
waiting state (STATUS = 2).
Step 4 –
Repeat step 5 and 6 until STACK is empty
Step 5 –
Remove the topt node N of STACK. Process N and change the status
of N to the processed state (STATUS = 3).
Step 6 –
Add to the top of STACK all the neighbors of N that are in ready state
(STATUS = 1) and change their status to the waiting state (STATUS =
2)
Step 7 –
End
Minimum Cost Spanning Tree: 



Let G = (V, E) be an undirected connected graph with vertices ‘V’ and edges ‘E’.
A sub-graph t = (V, E’) of the G is a Spanning tree of G if and only if ‘t’ is a tree.
The problem is to generate a graph G’= (V, E) where ‘E’ is the subset of E, G’ is a
Minimum spanning tree.
Each and every edge will contain the given non-negative length. Connect all the nodes
with edge present in set E’ and weight has to be minimum.
NOTE: 

We have to visit all the nodes.
The subset tree i.e. any connected graph with ‘N’ vertices must have at least N-1
edges and also it does not form a cycle.
Definition: 
A spanning tree of a graph is an undirected tree consisting of only those edge that are
necessary to connect all the vertices in the original graph.
 A Spanning tree has a property that for any pair of vertices there exist only one path
between them and the insertion of an edge to a spanning tree form a unique cycle.
Application of the spanning tree: Page 123
1. Analysis of electrical circuit.
2. Shortest route problems.
Minimum cost spanning tree: 

The cost of a spanning tree is the sum of cost of the edges in that tree.
There are 2 method to determine a minimum cost spanning tree are: 1. Kruskal’s Algorithm
2. Prim’s Algorithm.
KRUSKAL’S ALGORITHM: In kruskal's algorithm the selection function chooses edges in increasing order of length
without worrying too much about their connection to previously chosen edges, except that
never to form a cycle. The result is a forest of trees that grows until all the trees in a forest (all
the components) merge in a single tree.
 In this algorithm, a minimum cost-spanning tree ‘T’ is built edge by edge.
 Edges are considered for inclusion in ‘T’ in increasing order of their cost.
 An edge is included in ‘T’ if it doesn’t form a cycle with edge already in T.
 To find the minimum cost spanning tree the edge are inserted to tree in increasing
order of their cost
Algorithm: Algorithm kruskal(E, cost, n, t)
//E  set of edges in G has ‘n’ vertices.
//cost[u, v]  cost of edge (u, v). t  set of edge in minimum cost spanning tree
// the first cost is returned.
{
for i := 1 to n do parent[i] := -1;
i := 0; mincost := 0.0;
While ((i < n-1)and (heap not empty)) do
{
j := find(n);
k := find(v);
if (j not equal k) than
{
Page 124
i := i + 1
t[i, 1] := u;
t[i, 2] := v;
mincost := mincost + cost[u, v];
union(j, k);
}
}
if(i notequal n-1) then write(“No spanning tree”)
else return minimum cost;
}
Analysis: 
The time complexity of minimum cost spanning tree algorithm in worst case is O(|E|
log |E|),
 Where E is the edge set of G.
Example: - Step by Step operation of Kurskal’s algorithm.
Step 1 – In the graph, the Edge(g, h) is shortest. Either vertex g or vertex h could be
representative. Lets choose vertex g arbitrarily.
Step 2 – The Edge (c, i) creates the second tree. Choose vertex c as representative for second
tree.
Step 3 – Edge (g, g) is the next shortest edge. Add this edge and choose vertex g as
representative.
Page 125
Step 4 – Edge (a, b) creates a third tree.
Step 5 – Add edge (c, f) and merge two trees. Vertex c is chosen as the representative.
Step 6 – Edge (g, i) is the next next cheapest, but if we add this edge a cycle would be
created. Vertex c is the representative of both.
Step 7 – Instead, add edge (c, d).
Step 8 – If we add edge (h, i), edge(h, i) would make a cycle.
Page 126
Step 9 – Instead of adding edge (h, i) add edge (a, h).
Step 10 – Again, if we add edge (b, c), it would create a cycle. Add edge (d, e) instead to
complete the spanning tree. In this spanning tree all trees joined and vertex c is a sole
representative.
PRIM'S ALGORITHM
Start from an arbitrary vertex (root). At each stage, add a new branch (edge) to the
tree already constructed; the algorithm halts when all the vertices in the graph have been
reached.
Algorithm: Algorithm Prims(e, cost, n, t)
{
Let (k, l) be an edge of minimum cost in E;
Mincost := cost[k, l];
Page 127
T[1,1] := k; t[1,2] := l;
For i := 1 to n do
If (cost[i, l] < cost[i, k]) then near[i] := l;
Else near[i] := k;
Near[k] := near[l] := 0;
For i := 2 to n-1 do
{
Let j be an index such that near[j] ≠ 0 and
Cost[j, near[j]] is minimum;
T[i,1] := j; t[i, 2] := near[j];
Mincost := Mincost + Cost[j, near[j]];
Near[j] := 0;
For k := 0 to n do
If near((near[k]≠0) and (Cost[k, near[k]]>cost[k, j])) then
Near[k] := j;
}
Return mincost;
}



The Prim’s algorithm will start with a tree that includes only a minimum cost edge of
G.
Then, edges are added to the tree one by one. The next edge (i, j) to be added in such
that I is a vertex included in the tree, j is a vertex not yet included, and cost of (i, j),
cost[i, j] is minimum among all the edges.
The working of Prims will be explained by following diagram: -
Step 1:
Step 2:
Step 3:
Step 4:
Step 5:
Step 6:
Page 128
Page 129
UNIT – V
Searching and Sorting: Searching: Searching refers to an operation of finding the location of the searching data in
collection of elements and output some message if data does not exist in the list. The search is
said to be successful if data appears in the collection else it is called unsuccessful.
There are two methods of searching:  Linear Search
 Binary Search
1. Linear Search: This is the simplest technique to find out an element in an unsorted list. The
element can be start finding from first element to last element. If the element is
finding on the particular position, then process that position and if it is not found then
display a message.
Algorithm – LinearSearch(Arr, n, s)
Description – Arr is an array of n elements and n is a natural number that represents
the upper bound of array. s is the searching number.
Begin
For i = 0 TO n-1 Step 1
If s = Arr[i] Then
Return i
[End of if statement]
[End of For statement]
Return -1
End
Analysis of complexity of Linear Search: In searching and sorting, we take time complexity in worst case, average case and best
case. In best case we assume that the element is found at the first position of list. In worst
case we assume that the element is not found till the last and in average case we assume that
the element is present at the mid of the list. If the element is not present in the list, then the
time taken is O(n) which is worst case. In case of average, element is found at the mid of the
list. The number of comparison would be n/2.
2. Binary Search: In this searching method, first we required the array elements is ascending
order then we can obtain the element with an algorithm called Binary search. We
define positions low on 0 and high of n-1 element and then determine the middle
position then compare the searching number from middle value and if the value
matches then display the position but if not then either the first or second half of the
array can be selected from next comparison. This process continues until a match is
found or there are no values left.
Page 130
Algorithm – BinarySearch(Arr, n, s)
Description – Arr is a sorted array of n elements and n is a natural number that
represents the upper bound of array. s is the searching number.
Begin
[Initialize] low = 0, high = n-1
While low<=high do
Mid = (low + high) / 2
If s = Arr[mid] Then
Return mid
Else if s < Arr[mid] Then
high = mid – 1
Else
low = mid + 1
[End of if statement]
[End of For statement]
Return -1
End
Time complexity of Binary Search: Measure of complexity is f(n) which is the number of comparison to locate a value in
collection of elements. It can be anluzed that each comparison reduces the search in half.
2f(n) > n
f(n) = [log2n] + 1
Sorting: Sorting means arranging the elements in the ascending or descending order. There are
various sorting methods: 1. Bubble Sort: It is very simple sorting technique but not very efficient in comparison to
another sorting techniques. In this method, each element is compared with adjacent
elements. If first element is larger than second element then interchange their location,
otherwise not. Then next element is compared with its adjacent element and the same
process is repeated for all the elements in the list. During the first pass, largest
element positioned at last location in list. During the second pass, the same process is
repeated leaving the largest element and so on.
Algorithm – Bubblesort(Arr, n)
Begin
For i = 0 to n – 1 step 1
For j = 0 to n – i – 1 step 1
If Arr [ j ] > Arr [ j + 1] Then
t = Arr [ j ]
Arr [ j ] = Arr [ j + 1]
Arr [ j + 1] = t
Page 131
[End of if statement]
[End of for statement]
[End of for statement]
End
Example –
#include<stdio.h>
#include<conio.h>
void main( )
{
int x[20],i,n;
void bubblesort(int [], int);
clrscr( );
printf("how many numbers - ");
scanf("%d", &n);
for(i=0 ; i<n; i++)
{
printf("enter the value - ");
scanf("%d", &x[i]);
}
printf("\nBefore sorting...........");
for(i=0 ; i<n; i++)
printf("\n %d", x[i]);
bubblesort(x,n);
printf("\nAfter sorting...........");
for(i=0; i<n; i++)
printf("\n %d", x[i]);
getch( );
}
void bubblesort(int x[], int n)
{
int i,j,t;
for(i=0 ; i<n ; i++)
{
for(j=0 ; j<n-i-1 ; j++)
{
if(x[j] > x[j+1])
{
t = x[j];
x[j] = x[j+1];
x[j+1] = t;
}
}
}
}
Page 132
2. Selection Sort: In this sorting method, first to find the highest element in the array and
interchange it with the value in last position of array. Now, find the second highest
element in the remainder of array and interchange it with a value in the second last
position, carry on till we have reached the first of array. Now all elements have been
sorted into asceding order.
Algorithm – Selectionsort(Arr, n)
Begin
For i = 0 to n – 1 step 1
max = Arr[0]
p=0
For j = 1 to n – i -1 step 1
If Arr [ j ] > max Then
max = Arr [ j ]
p=j
[End of if statement]
[End of for statement]
Arr [ p ] = Arr [n – i – 1]
Arr [n – i – 1] = max
[End of for statement]
End
Example –
#include<stdio.h>
#include<conio.h>
void main( )
{
int x[20],i,n;
void selectionsort(int [],int);
clrscr( );
printf("how many numbers - ");
scanf("%d", &n);
for(i=0 ; i<n; i++)
{
printf("enter the value - ");
scanf("%d", &x[i]);
}
printf("\nBefore sorting...........");
for(i=0 ; i<n; i++)
printf("\n %d", x[i]);
selectionsort(x,n);
printf("\nAfter sorting...........");
for(i=0 ; i<n; i++)
Page 133
printf("\n %d", x[i]);
getch( );
}
void selectionsort(int x[], int n)
{
int i, j, max, p;
for(i=0 ; i<n; i++)
{
max = x[0];
p=0;
for(j=0 ; j<n-i; j++)
{
if(x [ j ] > max)
{
max = x [ j ];
p = j;
}
}
x [ p ] = x [n-i-1];
x [n-i-1] = max;
}
}
3. Insertion Sort: In insertion sort, we assume the first element Arr[0] in pass 1 is already sorted.
In pass 2, the next second element Arr[1] is compared with the first one and inserted
into its proper place either before or after the first element. In pass 3, the third
element Arr[2] is inserted into proper place and so on.
Algorithm – Insertionsort(Arr, n)
Arr is an array with n elements.
Begin
For i = 1 to n – 1 step 1
t = Arr [ i ]
For j = i – 1 to 0 And t < Arr [ j ] step -1
Arr [ j + 1 ] = Arr [ j ]
[End of for statement]
Arr [ j+1 ] = t
[End of for statement]
End
Example –
#include<stdio.h>
#include<conio.h>
void main( )
{
Page 134
int x[20],i,n;
void insertionsort(int [], int);
clrscr( );
printf("how many numbers - ");
scanf("%d", &n);
for(i=0; i<n; i++)
{
printf("enter the value - ");
scanf("%d", &x[i]);
}
printf("\nBefore sorting...........");
for(i=0; i<n; i++)
printf("\n %d",x[i]);
insertionsort(x, n);
printf("\nAfter sorting...........");
for(i=0; i<n; i++)
printf("\n %d", x[i]);
getch( );
}
void insertionsort(int x[], int n)
{
int i, j, t;
for(i=1 ; i<n; i++)
{
t = a[i];
for(j=i-1 ; j>=0 && t<x[ j ]; j--)
{
x[ j + 1 ] = x[ j ];
}
x[ j+1 ] = t;
}
}
4. Quick Sort: It is developed be C.A.R. Hoare. It is also known as partition exchange sort. It
is based on Divide and Conquer method. The Quick sort algorithm works by
partitioning the array to be sorted. Each partition is in turn sorted recursively. In this
method, we divide the list stored in the array into two parts and so on and keep track
of middle element. In this sorting, we continue to divide the list into two parts until
elements in list not remain single, and list finally gets sorted.
Algorithm – Quicksort(X, n, low, high)
X is an array with n elements. The low points to the 0th element and high points to the
n-1
Page 135
element.
Begin
If low < high Then
p = Partition(X, low, high, p)
Quicksort(X, n, low, p – 1)
Quicksort(X, n, p + 1, high)
[End of for statement]
End
Algorithm – Partition(X, beg, end, loc)
X is an array with n elements. The low points to the 0th element and high points to the
n-1
element.
Begin
loc = first = beg
last = end
flag = 0
While (!flag) do
While x[last] >= x[loc] And *loc != last
last = last – 1
[End of while loop]
If *loc = last Then
flag = 1
Else
If x[loc] > x[last] Then
temp = x[loc]
x[loc] = x[last]
x[last] = temp
loc = last
[End of if statement]
If (!flag) Then
While x[first] <= x[loc]) And loc != first
first = first + 1
[End of while loop]
If loc = first Then
flag = 1
Else
If x[loc] < x[first] Then
temp = x[loc]
x[loc] = x[first]
x[first] = temp
loc = first
[End of if statement]
[End of if statement]
[End of if statement]
Page 136
[End of if statement]
[End of while loop]
End
Example –
#include<stdio.h>
#include<conio.h>
void quicksort(int [], int, int, int);
void partition(int [], int, int, int *);
void main( )
{
int x[20],i,n;
clrscr( );
printf("how many numbers - ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("enter the value - ");
scanf("%d",&x[i]);
}
printf("\nBefore sorting...........");
for(i=0;i<n;i++)
printf("\n %d",x[i]);
quicksort(x,n,0,n-1);
printf("\nAfter sorting...........");
for(i=0;i<n;i++)
printf("\n %d",x[i]);
getch( );
}
void quicksort(int x[], int n, int low, int high)
{
int loc;
if(low < high)
{
partition(x,low,high,&loc);
quicksort(x,n,low,loc-1);
quicksort(x,n,loc+1,high);
}
}
void partition(int x[], int beg, int end, int *loc)
{
int first,last,flag,temp;
*loc = first = beg;
last = end;
flag = 0;
Page 137
while (!flag)
{
while (x[last] >= x[*loc] && (*loc != last))
last --;
if (*loc == last)
flag = 1;
else
{
if (x[*loc] > x[last])
{
temp = x[*loc];
x[*loc] = x[last];
x[last] = temp;
*loc = last;
}
}
if (!flag)
{
while ((x[first] <= x[*loc]) && (*loc != first))
first++;
if (*loc == first)
flag = 1;
else
{
if (x[*loc] < x[first])
{
temp = x[*loc];
x[*loc] = x[first];
x[first] = temp;
*loc = first;
}
}
}
}
}
5. Shell Sort: It is developed be Donald Shell. It is also based on Divide and Conquer
method. The shell sort algorithm works by calculating the d (distance) by mid
position of array. Each element of first part is compared with element of second part
that is caculated as distance. In this method, we divide the list stored in the array into
two parts and so on and keep track of middle element.
Algorithm – Shellsort(X, n)
X is an array with n elements.
Page 138
Begin
d = n/2
While d >= 1 do
For i = 0 to n – d Step 1
If x[i] > x[i+d] Then
t = x[i]
x[i] = x[i+d]
x[i+d] = t
[End of if statement]
[End of for statement]
If d = 1 Then
Return
d = d / 2.0 + 0.5
[End of while statement]
End
Example –
#include<stdio.h>
#include<conio.h>
void main( )
{
int x[20], i, n;
void shellsort(int [], int);
clrscr( );
printf("how many numbers - ");
scanf("%d", &n);
for(i=0 ;i<n ;i++)
{
printf("enter the value - ");
scanf("%d", &x[i]);
}
printf("\nBefore sorting...........");
for(i=0;i<n;i++)
printf("\n %d",x[i]);
shellsort(x,n);
printf("\nAfter sorting...........");
for(i=0;i<n;i++)
printf("\n %d",x[i]);
getch( );
}
void shellsort(int x[], int n)
{
int i, t, d;
d = n/2;
while(d >= 1)
Page 139
{
for(i=0 ; i<n-d ; i++)
{
if(x[i] > x[i+d])
{
t = x[i];
x[i] = x[i+d];
x[i+d] = t;
}
}
if(d = = 1)
return;
d = d / 2.0 + 0.5;
}
}
6. Merge Sort: In this sorting technique which divides the array into subarray of same size
and merges adjacent pairs then we have approximately n / 2 arrays of same size. This
process is repeated until there is only one array remaining of size n.
Each pass of the merge sort will start at the beginning of array X and merge
pairs of sorted sub-arrays in a common single array.
Example #include<stdio.h>
#include<conio.h>
void mergesort(int [],int,int);
void mergingsortedsubarrays(int [], int, int, int, int);
void main( )
{
int x[20], i , n;
clrscr( );
printf("how many numbers - ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("enter the value - ");
scanf("%d",&x[i]);
}
printf("\nBefore sorting...........");
for(i=0;i<n;i++)
printf("\n %d",x[i]);
mergesort(x,0,n-1);
printf("\nAfter sorting...........");
for(i=0;i<n;i++)
Page 140
printf("\n %d",x[i]);
getch( );
}
void mergesort(int x[], int low, int high)
{
int mid;
if(low < high)
{
mid = (low+high)/2;
mergesort(x, low, mid);
mergesort(x, mid+1, high);
mergingsortedsubarrays(x, low, mid, mid+1, high);
}
}
void mergingsortedsubarrays(int x[], int lb, int lr, int rb, int rr)
{
int a, b, c, k, final[20];
a = lb;
b = rb;
c = lb;
while((a<=lr) && (b<=rr))
{
if(x[a] < x[b])
final[c] = x[a++];
else
final[c] = x[b++];
c++;
}
if(a > lr)
{
while(b <= rr)
final[c++] = x[b++];
}
else
{
while(a <=lr)
final[c++] = x[a++];
}
for(k = lb; k <= rr ; k++)
x[k] = final[k];
}
7. Heap Sort: It is a technique which sorts the elements of array that represent a tree with a
special property. A heap is defined as a balanced binary tree in which the value of
Page 141
each node is less than or equal to the value of the parent node. This implies that root
of the binary tree has the largest element in the heap.
Type of heap: 1.) Max Heap: - The tree in which the value of each node is less than or equal
to the value of parent node is known as max heap.
2.) Min Heap: - The tree in which the root of the binary tree has the smallest
element of the heap.
A binary tree will be heap when it satisfies following two conditions: 1.) Value of each node is less than or equal to the value of parent node.
2.) Each level of binary tree must be filled from left to right and a node should not be
placed on a new level until the preceding level is null.
Example - #include<stdio.h>
#include<conio.h>
void heapsort(int [], int);
void heap(int [], int);
void below_heap(int [], int, int);
void main( )
{
int x[20], i, n;
clrscr( );
printf("how many numbers - ");
scanf("%d", &n);
for(i=0; i<n ; i++)
{
printf("enter the value - ");
scanf("%d", &x[i]);
}
printf("\nBefore sorting...........");
for(i=0 ; i<n ; i++)
printf("\n %d", x[i]);
heapsort(x,n);
printf("\nAfter sorting...........");
for(i=0 ; i<n ; i++)
printf("\n %d", x[i]);
getch( );
}
void heapsort(int x[], int n)
{
int temp, i;
heap(x,n);
for(i = n-1; i>0; i--)
{
temp = x[0];
x[0] = x[i];
Page 142
x[i] = temp;
below_heap(x, 0, i-1);
}
}
void heap(int x[], int n)
{
int index, i;
index = (n-1) >> 1;
for(i=index ; i>=0 ; i--)
below_heap(x, i, n-1);
}
void below_heap(int x[], int first, int last)
{
int count, l_child, r_child, max, temp;
if(first = = 0)
l_child = 1;
else
l_child = first << 1;
r_child = l_child + 1;
if (l_child <= last)
{
max = x[l_child];
count = l_child;
if (r_child <= last)
{
if (x[r_child] > max)
{
max = x[r_child];
count = r_child;
}
}
if(x[first] < x[count])
{
temp = x[first];
x[first] = x[count];
x[count] = temp;
below_heap(x, count, last);
}
}
}
Page 143