Data Structure and Algorithm Explaned
Data Structure and Algorithm Explaned
ARCLER
P r e s s
www.arclerpress.com
Data Structure and Algorithm
Nikhat Raza Khan, Manmohan Singh, Piyush Kumar Shukla and Ramesh Prasad Aharwal
Arcler Press
224 Shoreacres Road
Burlington, ON L7L 2H2
Canada
www.arclerpress.com
Email: [email protected]
This book contains information obtained from highly regarded resources. Reprinted material
sources are indicated and copyright remains with the original owners. Copyright for images and
other graphics remains with the original owners as indicated. A Wide variety of references are
listed. Reasonable efforts have been made to publish reliable data. Authors or Editors or Publish-
ers are not responsible for the accuracy of the information in the published chapters or conse-
quences of their use. The publisher assumes no responsibility for any damage or grievance to the
persons or property arising out of the use of any materials, instructions, methods or thoughts in
the book. The authors or editors and the publisher have attempted to trace the copyright holders
of all material reproduced in this publication and apologize to copyright holders if permission has
not been obtained. If any copyright holder has not been acknowledged, please write to us so we
may rectify.
Notice: Registered trademark of products or corporate names are used only for explanation and
identification without intent of infringement.
Arcler Press publishes wide variety of books and eBooks. For more information about
Arcler Press and its products, visit our website at www.arclerpress.com
ABOUT THE AUTHORS
List of Figures.........................................................................................................xi
List of Tables.........................................................................................................xv
List of Abbreviations........................................................................................... xvii
Preface............................................................................................................ ....xix
Chapter 1 Prerequisite................................................................................................ 1
1.1. Introduction......................................................................................... 2
1.2. Concept of Data Representation.......................................................... 2
1.3. Data Structures.................................................................................... 2
1.4. Structural Programming....................................................................... 4
1.5. Top-Down Design................................................................................ 6
1.6. Abstract Data Type............................................................................... 6
1.7. Array.................................................................................................... 7
1.8. Structure............................................................................................ 39
1.9. Character Strings................................................................................ 44
1.10. Pointers........................................................................................... 45
1.11. Dynamic Memory Management...................................................... 48
1.12. Pointer to Structure.......................................................................... 50
Chapter 3 Trees........................................................................................................ 89
3.1. Introduction....................................................................................... 90
3.2. Basic Concepts.................................................................................. 90
3.3. Tree................................................................................................... 91
3.4. Binary Tree........................................................................................ 92
3.5. Traversals Operation of a Binary Tree............................................... 110
3.6. Threaded Binary Tree....................................................................... 117
3.7. Binary Expression Tree..................................................................... 119
3.8. Conversion of General Tree to Binary Tree....................................... 120
3.9. Applications of Tree......................................................................... 122
3.10. Sequential or Linear Search........................................................... 127
3.11. Binary Search................................................................................ 133
3.12. Height Balanced Tree..................................................................... 140
3.13. Weight Balanced Tree.................................................................... 141
3.14. Multiway Search Trees................................................................... 142
3.15. Digital Search Trees....................................................................... 143
3.16. Hashing......................................................................................... 144
viii
Chapter 6 Algorithm and Its Analysis...................................................................... 269
6.1. Analysis of Algorithm....................................................................... 270
Bibliography........................................................................................... 315
Index...................................................................................................... 317
ix
LIST OF FIGURES
xii
Figure 4.8 Heap Insertion at the root
Figure 4.9 Heap Insertion at the root
Figure 4.10 Heap Insertion at the root
Figure 5.1. A graph
Figure 5.2 Adjacent Vertices
Figure 5.3. A directed graph
Figure 5.4. An undirected graph
Figure 5.5. Strongly connected graph
Figure 5.6. A weakly directed graph
Figure 5.7. Unconnected graph
Figure 5.8. Simple and multi graph
Figure 5.9. Trees
Figure 5.10 . Adjacency Matrix
Figure 5.11 Adjacency Matrix for Directed Graph
Figure 5.12 Adjacency List Representation
Figure 5.13. Adjacency list structure for graph
Figure 5.14 Minimum Path Problem
Figure 5.15. Graph for DFS
Figure 5.16. Graph for BFS
Figure 5.17 Graph has four distinct spanning trees
Figure 5.18 Graph has four distinct spanning trees
Figure 5.19 Sequence of diagrams depicts the operation of Prim’s algorithm
Figure 5.20 Sequence of Kruskal Algorithm
Figure 5.21 A separate tree
Figure 5.22 spanning tree
Figure 5.23 Delete these edges from panning tree
Figure 5.24 Spanning tree not create cycle
Figure 5.25 sequence of diagrams illustrates the operation of Dijkstra’s algorithm
xiii
LIST OF TABLES
CONTENTS
1.1. Introduction......................................................................................... 2
1.2. Concept of Data Representation.......................................................... 2
1.3. Data Structures.................................................................................... 2
1.4. Structural Programming....................................................................... 4
1.5. Top-Down Design................................................................................ 6
1.6. Abstract Data Type............................................................................... 6
1.7. Array.................................................................................................... 7
1.8. Structure............................................................................................ 39
1.9. Character Strings................................................................................ 44
1.10. Pointers........................................................................................... 45
1.11. Dynamic Memory Management...................................................... 48
1.12. Pointer to Structure.......................................................................... 50
2 Data Structure and Algorithm
1.1. INTRODUCTION
In this chapter, concept of data, data structure, structural programming, top–
down design, abstract data type, array, structure, character strings, pointers,
dynamic memory allocation and pointer to structure is covered. In array
one, two, and multi-dimensional arrays with their operations are discussed.
The implementation of structure is covered with the help of example. The
character strings with their storage structure and operations are covered in
this chapter. The pointer with their dynamic allocation is also discussed. The
implementation of structure with the help of pointer is also covered.
describes a set of similar objects. However, abstract data type operations are
user defined.
In defining an abstract data type as a mathematical concept, we are not
concerned with its implementation issues like- time and space requirements.
To understand ADT clearly, let us see, which is meant by abstraction.
An abstraction is the structuring of a nebulous problem into well-defined
entities by defining their data and operations. Consequently, these entities
combine data operations. They are not decoupled from each other.
The data structure can only be accessed with defined operations. This set
of operations is called interface and is exported by the entity. An entity with
the properties just described is called an abstract data type(ADT).
Figure 1.5 shows an ADT, which consists of abstract data structure and
operations. Only the operations are viewable from the outside and define the
interface.
1.7. ARRAY
“An array is a structured data type made up of a finite, fixed size, collection
of homogenous ordered elements.”
Homogenous means, all the elements are of the same data type, ordered
means all elements are arranged sequentially, finite means there is a last
element and fixed size means that the size of the array must be known at
compile time.
The accessing mechanism of array is direct, which means we can
access any element directly without first accessing the preceding elements;
accessing is done by the use of an index that allows us to specify the desired
element by giving its position in the collection.
8 Data Structure and Algorithm
total number of cells required for storage, we shall proceed in the following
manner:
B = 20
L =2
I=6
S=4
Address of X[6] = 20 + (6 – 2) × 4
= 20 + 4 × 4
= 20 + 16
= 36
Number of cell = [(20 – 2) + 1] × 4
= [18 + 1] × 4
= 19 × 4
= 76
Index Info
0 25
1 30
2 40
3 50
double salary[] = {1000,2000,3000,4000,5000};
In this case, the computer is able to calculate the size of the array.
The number of initializers can be equal to or less than the size of the
array. It cannot be more than the size of the array. The following initialization
Prerequisite 11
Index Info
0 4
1 8
2 12
3 16
12 Data Structure and Algorithm
4 20
5 24
6 28
7 32
8 36
9 40
i. Algorithm: Following are the steps for traversal operation:
a. [Initialize the counter]
Set (counter) i = 0
b. [Traverse each element of the array]
Repeat Step (c) and (d) while i <= n
c. [Visit element and performs the operation]
Apply operation to list[i]
d. [Increment counter]
Set i:= i +1
e. End.
ii. Equivalent C Function:
void traversal(int list[], int n)
{
int i;
i=0;
while(i<n)
{
printf(“Element at position %d is:,”i);
printf(“%d\n,”list[i]);
i++;
}
}
iii.Implementation of Traversal Function: The following program
array_traversal.c shows the array implementation of the traversal
function for integers stored in the computer memory:
/*array_traversal.c*/
Prerequisite 13
#include<stdio.h>
#include<stdlib.h>
void traversal(int[],int);
void main()
{
int i=0,list[100],n;
printf(“This program performs the one dimensional array traversal operation
on numbers!\n”);
printf(“How many numbers in the array:”);
scanf(“%d,”&n);
printf(“!!Please enter the number!!\n”);
while(i<n)
{
printf(“Input value for the %d:,”i);
scanf(“%d,”&list[i]);
i++;
}
traversal(list,n);
}
void traversal(int list[], int n)
{
int i=0;
printf(“!!Entered element in the array after traversing the array are!!\n”);
while(i<n)
{
printf(“Element at position %d is:,”i);
printf(“%d\n,”list[i]);
i++;
}
printf(“\n”);
}
14 Data Structure and Algorithm
Index Info
0 4
1 8
2 12
3 16
4 20
5 28
6 32
7 36
8 40
9
Index Info
0 4
1 8
2 12
3 16
4 20
5 24
6 28
7 32
8 36
9 40
I=9 [Represents number of elements in the array]
TABLE[9]=TABLE[8]=40
I = I –1 = 9–1
TABLE[8]=TABLE[7]=36
I = I –1 = 8–1
TABLE[7]=TABLE[6]=32
I = I –1 = 7–1
16 Data Structure and Algorithm
TABLE[6]=TABLE[5]=28
I = I –1 = 6–1
TABLE[5]=24[Newly inserted element]
The result after insertion of 24 is shown in Table 1.3(b).
i. Algorithm: Following are the steps for insertion operation:
a. [Initialize the counter with the size of the array]
Set (counter) i:= n
b. [Traverse each element of the array until we find the desired
position]
Repeat step (c) and (d) while i >= position(desired position)
c. [Move element downward]
Set list[i+1]:= list[i]
d. [Decrease counter]
Set i:= i –1
e. [Insert element at the desired position]
Set list[position]:= item
f. [Reset the array size]
Set n = n+1
g. [Return the new array size]
return(n)
h. End.
ii. Equivalent C Function
int insertion(int list[], int n, int position, int item)
{
int i;
i=n;
while(i>=position)
{
list[i+1] = list[i];
i– –;
}
list[position] = item;
Prerequisite 17
n= n+1;
return n;
}
iii.
Implementation of Insertion Function: The following program
array_insertion.c shows the array implementation of the insertion
function for integers stored in the computer memory:
/*array_insertion.c*/
#include<stdio.h>
#include<stdlib.h>
int insertion(int[],int,int,int);
void display(int[],int);
void main()
{
int i=0,list[100],n,position,item;
printf(“This program performs the one dimensional array insertion operation
on numbers!\n”);
printf(“How many numbers are there in the array:”);
scanf(“%d,”&n);
printf(“!!Please enter the number!!\n”);
while(i<n)
{
printf(“Input value for the %d:,”i);
scanf(“%d,”&list[i]);
i++;
}
display(list,n);
printf(“Enter the position where we want to add a new number:”);
scanf(“%d,”&position);
printf(“Please enter the number for the position:”);
scanf(“%d,”&item);
n = insertion(list,n,position,item);
18 Data Structure and Algorithm
display(list,n);
}
void display(int list[], int n)
{
int i=0;
printf(“!!Entered elements in the array are!!\n”);
while(i<n)
{
printf(“Element at position %d is:,”i);
printf(“%d\n,”list[i]);
i++;
}
printf(“\n”);
}
int insertion(int list[], int n, int position, int item)
{
int i;
i=n;
while(i>=position)
{
list[i+1] = list[i];
i– –;
}
list[position] = item;
n= n+1;
return n;
}
iv.Output of the Program: This program performs the one
dimensional array insertion operation on numbers!
How many numbers are there in the array: 5
!!Please enter the number!!
Input value for the 0: 12
Prerequisite 19
Index Info
0 12
1 23
2 34
3 45
4 56
5 67
6 78
7 89
Prerequisite 21
Index Info
0 12
1 23
2 34
3 56
4 67
5 78
6 89
7
int i,item;
i=n;
item = list[position];
printf(“Deleted item from the position %d is:%d\n,”position,item);
while(position<=n)
{
list[position] = list[position+1];
position++;
}
n= n–1;
return n;
}
iv.
Output of the Program: This program performs the one
dimensional array deletion operation on numbers!
How many numbers are there in the array: 5
!!Please enter the number!!
Input value for the 0: 12
Input value for the 1: 23
Input value for the 2: 34
Input value for the 3: 45
Input value for the 4: 56
!!Entered elements in the array are!!
Element at position 0 is: 12
Element at position 1 is: 23
Element at position 2 is: 34
Element at position 3 is: 45
Element at position 4 is: 56
Enter the position from where we want to delete a number: 3
Deleted item from the position 3 is: 45
!!Entered elements in the array are!!
Element at position 0 is: 12
Element at position 1 is: 23
24 Data Structure and Algorithm
n=5
LOC(LIST[5,2]) = 100 + 5 × [5 × (5 – 1) + (2 – 1)]
= 100 + 5 × [5 × 4 + 1]
= 100 + 5 × [20 + 1]
= 100 + 5 × 21
= 100 + 105
= 205
To find the total number of cells required for a two dimensional array,
we use the following formula:
Number of elements = [(UB of I’st Dim. – LB of I’st Dim)+1] × [(UB of
II’nd Dim. – LB of II’nd Dim)+1]
Number of Cell = No. of elements x size
For example, let us take an array LIST[20,5]. Suppose the size of each
element is 2 unit, find out the total number of cells required for storage.
UB of I’st Dim. = 20
LB of I’st Dim = 1
UB of II’nd Dim. = 5
LB of II’nd Dim = 1
No. of elements = [(UB of I’st Dim. – LB of I’st Dim)+1] × [(UB of
II’nd Dim. – LB of II’nd Dim)+1]
No. of elements = [(20 – 1) + 1] × [(5 – 1) + 1]
= [19 + 1] × [4 + 1]
= 20 ×5
= 100
Number of Cell = No. of elements x size
= 100 ×2
= 200
For example,
int list[3][4];
char color[30][21];
In the first declaration the list can be thought of as a table having three rows
and four columns. Similarly, In the second declaration color is the array
name; the array color in an array of 30 names of color, each name consists
of not more than 20 characters, the last character being the string terminator
‘\0.’
second subscript increases most rapidly. If there are too few values within
a pair of braces, the remaining elements of that row will be assigned zeros.
The number of values within each pair of braces cannot exceed the defined
row size.
For example,
int list[3][4] = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
Here, the four values in the first inner pair of braces are assigned to the
array elements in the first row, the values in the second inner pair of braces
are assigned to the array elements in the second row and so on. After the
initialization the array list will take the initial values as follows:
list[0][0] = 1 list[0][1] = 2 list[0][2] = 3 list[0][3] = 4
list[1][0] = 5 list[1][1] = 6 list[1][2] = 7 list[1][3] = 8
list[2][0] = 9 list[2][1] = 10 list[2][2] = 11 list[2][3] = 12
Let us take another example in which we assign values only to the first
three elements in each row.
int list[3][4] = {
{1,2,3},
{5,6,7},
{9,10,11}
};
After the initialization the array list will take the initial values as follows:
list[0][0] = 1 list[0][1] = 2 list[0][2] = 3 list[0][3] = 0
list[1][0] = 5 list[1][1] = 6 list[1][2] = 7 list[1][3] = 0
list[2][0] = 9 list[2][1] = 10 list[2][2] = 11 list[2][3] = 0
The last element in each row is assigned a value of zero.
For example,
int list[3][4] = {
{1,2,3,4,5},
{6,7,8,9,10},
28 Data Structure and Algorithm
{11,12,13,14,15}
};
In this case the compiler will generate the error message, since the
number of values in each pair of braces exceeds the defined array size.
Let us take an example in which we take the two dimensional array of
character.
char book[5][21] =
{
“Data,”
“Structure,”
“By,”
“Sanjay,”
“Jain”
};
The first index indicates strings, “Data,” “Structure” etc. and the second
index specifies the characters in the string. Each string in the array consists
of 21 characters including the string terminator.
The number of characters may be less than the specified number in the
array, the unfilled places will be filled in by ‘\0’; however, the number cannot
exceed the maximum value of second index.
i– –;
}
strcpy(book[position],item);
n= n+1;
return n;
}
iii.
Implementation of Insertion Function: The following program
array_two-dim_insertion.c shows the array implementation of
the insertion function for strings of books stored in the computer
memory:
/*array_two-dim_insertion.c*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int insertion(char[][20],int,int,char[]);
void display(char[][20],int);
void main()
{
int i=1,n,position;
char book[10][20],item[20];
printf(“This program performs the two dimensional array insertion operation
on strings of books!\n”);
printf(“How many books in the array:”);
scanf(“%d,”&n);
printf(“!!Please enter the books as a whole string!!\n”);
while(i<=n)
{
printf(“Input book name (%d) in a single string:,”i);
scanf(“%s,”&book[i]);
i++;
}
display(book,n);
Prerequisite 33
d. [Increase counter]
Set position:= position +1
e. [Reset the array size]
Set n = n–1
f. [Return the new array size]
return(n)
g. End.
ii. Equivalent C Function
int deletion(char book[][20], int n, int position)
{
int i;
char item[20];
i=n;
strcpy(item,book[position]);
printf(“Deleted book from the position %d is: %s\n,” position,item);
while(position<=n)
{
strcpy(book[position],book[position+1]);
position++;
}
n= n–1;
return n;
}
iii.
Implementation of Deletion Function: The following program
array_two-dim_deletion.c shows the array implementation of
the deletion function for strings of books stored in the computer
memory:
/*array_two-dim_deletion.c*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int deletion(char[][20],int,int);
36 Data Structure and Algorithm
void display(char[][20],int);
void main()
{
int i=1,n,position;
char book[10][20];
printf(“This program performs the two dimensional array deletion operation
on strings of books!\n”);
printf(“How many books in the array:”);
scanf(“%d,”&n);
printf(“!!Please enter the books as a whole string!!\n”);
while(i<=n)
{
printf(“Input book name (%d) in a single string:,”i);
scanf(“%s,”&book[i]);
i++;
}
display(book,n);
printf(“Enter the position from where we want to delete a book name:”);
scanf(“%d,”&position);
n = deletion(book,n,position);
display(book,n);
}
void display(char book[][20], int n)
{
int i=1;
printf(“!!Entered Books in the list are!!\n”);
while(i<=n)
{
printf(“Book name at %d place is:,”i);
printf(“%s\n,”book[i]);
i++;
Prerequisite 37
}
printf(“\n”);
}
int deletion(char book[][20], int n, int position)
{
int i;
char item[20];
i=n;
strcpy(item,book[position]);
printf(“Deleted book from the position %d is:%s\n,”position,item);
while(position<=n)
{
strcpy(book[position],book[position+1]);
position++;
}
n= n–1;
return n;
}
iv.
Output of the Program: This program performs the two
dimensional array deletion operation on strings of books!
How many books in the array: 5
!!Please enter the books as a whole string!!
Input book name (1) in a single string: D.S.
Input book name (2) in a single string: A.I.
Input book name (3) in a single string: C.G.
Input book name (4) in a single string: Networking
Input book name (5) in a single string: T.O.C
!!Entered Books in the list are!!
Book name at 1 place is: D.S.
Book name at 2 place is: A.I.
38 Data Structure and Algorithm
1.8. STRUCTURE
In previous topic we studied about the array, which is a data structure whose
elements are all of the same type. We now turn our attention to the structure,
which is a data structure whose individual elements can differ in data types.
These individual elements of a structure are called structure members. So,
the structure may contain different types of members like integer, character,
and float. All the members of the structure are logically related.
Let us take an example of telephone list of all the users of BSNL in
Gwalior City. The list contains the following information about the users:
• Name;
• Telephone_Number;
• Profession;
• Address.
This telephone list of users can be represented with the help of the
structure.
keyword, tag_name is the name that appear in the structures type declaration,
and var1, var2, …varN are structure variables of type tag_name.
For example, the list of users of BSNL in Gwalior can be declared as:
struct Telephone_List
{
char Name[30];
int Telephone_Number[6];
char Profession[30];
char Address[80];
}
struct Telephone_List Telephone;
Where Telephone is a variable of type Telephone_List.
It is possible to combine the declaration of the structure composition with
that of the structure variables as follows:
storage-class struct tag_name
{
data_type member1;
data_type member2;
….
data_type memberN;
} var1,var2,…varN;
For example, the list of users of BSNL in Gwalior can be declared as:
struct Telephone_List
{
char Name[30];
int Telephone_Number[6];
char Profession[30];
char Address[100];
}Telephone;
Where Telephone is a variable of type Telephone_List.
It is possible to assign initial values to the members of the structure
variable, in much the same manner as the elements of the array. The initial
Prerequisite 41
values must appear in the order in which they will be assigned to their
corresponding structure members, enclosed in braces and separated by
commas. The syntax of this is:
stroage-class struct tag_name var1 = {value1,value2, …, valueN};
where; value1, value2, …, valueN refer to the values of the first member,
second member and so on, respectively.
char Profession[30];
char Address[80];
}Tele[100];
void main()
{
int i,n;
printf(“This program maintains the telephone list of the users of the BSNL
in Gwalior city!!!\n”);
printf(“Please enter how many records we want in the list:\n”);
scanf(“%d,”&n);
printf(“Please enter the information of the users\n”);
for(i=0;i<n;i++)
{
printf(“Name:”);
fflush(stdin);
gets(Tele[i].Name);
printf(“\nTelephone Number:”);
scanf(“%d,”Tele[i].Telephone_No);
printf(“\nProfession:”);
fflush(stdin);
gets(Tele[i].Profession);
printf(“\nAddress:”);
fflush(stdin);
gets(Tele[i].Address);
fflush(stdin);
}
printf(“\n List of the users”);
printf(“\n ###################\n”);
for(i=0;i<n;i++)
{
printf(“Name:%s,”Tele[i].Name);
Prerequisite 43
printf(“\nTelephone Number:%d,”Telephone[i].Tele_No);
printf(“\nProfession:%s,”Tele[i].Profession);
printf(“\nAddress:%s,”Tele[i].Address);
}
printf(“\n\n”);
}
• Output of the Program: This program maintains the telephone
list of the users of the BSNL in Gwalior city!!!
Please enter how many records we want in the list:
2
Please enter the information of the users
Name: Nikhat Khan
Telephone Number: 421403
Profession: Lecturer
Address: C/o. Rajendra Jain, Shinde Ki Chhawni, Lashker, Gwl.
Name: Alok Jain
Telephone Number: 230091
Profession: Student
Address: Hanuman Ghati, Lashker, Gwalior
!!! List of the users !!!
###################
Name: Nikhat Khan
Telephone Number: 421403
Profession: Lecturer
Address: C/o. Rajendra Jain, Shinde Ki Chhawni, Lashker, Gwl.
Name: Alok Jain
Telephone Number: 230091
Profession: Student
Address: Hanuman Ghati, Lashker, Gwalior
44 Data Structure and Algorithm
1.10. POINTERS
A pointer is a variable, which may contain the address of another variable.
All variables in C except variables of type register, have an address. The
address is the location where the variable exists in memory.
Pointers are used to access elements of array, pass arguments to a function
by reference in order to modify the original values of the arguments, transmit
arrays and strings to functions, pass functions as arguments to functions,
simplify representation of multi-dimensional arrays, allocate memory spaces
and create data structures. It is also applicable to all basic types of data and
derived data types like: structures, unions, functions, and files.
type_specifier *pointer_name;
where; pointer_name is the name of the pointer variable and type_specifier
refers to the data type of the pointer object.
For example,
char *p;
where; p is a pointer of type char. So, p may contain the address of a variable
of type char.
#include<stdio.h>
void main()
{
int A = 20;
char B = ‘P’;
double C = 12.24;
int *P1;
char *P2;
double *P3;
printf(“The following program shows the processing concepts of pointer
variables!!!!\n”);
printf(“Value of pointer(P1) without assigning address and without
indirection operator P1=%x\n,”P1);
printf(“Value of pointer(P1) without assigning address P1=%x\n,”*P1);
P1 = &A;
printf(“Value of pointer(P1) without indirection operator=%x\n,”P1);
printf(“Value of pointer(P1) P1=%d\n,”*P1);
printf(“Value of pointer(P2) without assigning address and without
indirection operatorP2=%x\n,”P2);
printf(“Value of pointer(P2) without assigning address P2=%x\n,”*P2);
P2 = &B;
printf(“Value of pointer(P2) without indirection operator P2=%x\n,”P2);
printf(“Value of pointer(P2) P2=%c\n,”*P2);
printf(“Value of pointer(P3) without assigning address and without
indirection operator P3=%x\n,”P3);
printf(“Value of pointer(P3) without assigning address P3=%x\n,”*P3);
P3 = &C;
printf(“Value of pointer(P3) without indirection operator P3=%x\n,”P3);
printf(“Value of pointer(P3) P3=%f\n,”*P3);
}
• Output of the Program: The following program shows the
processing concepts of pointer variables!!!!
48 Data Structure and Algorithm
the new dynamic variable, malloc will fail and will return NULL.
When a dynamic variable is no longer needed, the function call:
free(p);
Returns the space used by the dynamic variable to which p points to the
system. After the function free(p) is called, the pointer variable p is undefined
and so cannot be used until it is assigned a new value.
Let us take an example for showing the allocation and deallo-cation of
memory. The program pointer_allocation.c shows this process:
/*pointer_allocation.c*/
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
void main()
{
int *p,i;
printf(“The following program shows the dynamic allocation of pointer
variables!!!!\n”);
p = (int*)malloc(10*(sizeof(int)));
printf(“ADDRESS\t INFORMATION\n”);
for (i =0; i <10; i++)
{
*(p+i) = 20;
printf(“%x,”(p+i));
printf(“\t\t%d,”*(p+i));
printf(“\n”);
}
free(p);
}
•Output of the Program: The following program shows the
dynamic allocation of pointer variables!!!!
ADDRESS INFORMATION
780e90 20
50 Data Structure and Algorithm
780e94 20
780e98 20
780e9c 20
780ea0 20
780ea4 20
780ea8 20
780eac 20
780eb0 20
780eb4 20
}var *pointer_name;
pointer_name = &var;
Let us again discuss the same example as discussed in the case of
structure. The list of users of BSNL in Gwalior can be declared as:
struct {
char Name[30];
int Telephone_Number[6];
char Profession[30];
char Address[100];
}
Telephone_list, *Telephone;
Telephone = &Telephone_list;
An individual structure member can be accessed in terms of its
corresponding pointer variable by writing:
pointer_name->member
where; pointer_name refers to a structure type pointer variable and the
operator(->) is comparable to the period(.) operator as discussed in structure.
For example, in the list of users of BSNL in Gwalior the individual
members can be accessed as:
Telephone->Name;
Telephone->Telephone_Number;
Telephone->Profession;
Telephone->Address;
char Name[30];
int Telephone_No[6];
char Profession[30];
char Address[80];
}
Telephone, *Tele = &Telephone;
void main()
{
int i,n;
printf(“This program maintains the telephone list of the users of the BSNL
in Gwalior city!!!\n”);
printf(“Please enter how many records we want in the list:\n”);
scanf(“%d,”&n);
printf(“Please enter the information of the users\n”);
for(i=0;i<n;i++)
{
printf(“Name:”);
fflush(stdin);
gets(Tele->Name);
printf(“\nTelephone Number:”);
scanf(“%d,”&Tele->Telephone_No);
printf(“\nProfession:”);
fflush(stdin);
gets(Tele->Profession);
printf(“\nAddress:”);
fflush(stdin);
gets(Tele->Address);
fflush(stdin);
}
printf(“\n List of the users”);
printf(“\n ###################\n”);
Prerequisite 53
for(i=0;i<n;i++)
{
printf(“Name:%s,”Tele->Name);
printf(“\nTelephone Number:%d,”Tele->Telephone_No);
printf(“\nProfession:%s,”Tele->Profession);
printf(“\nAddress:%s,”Tele->Address);
}
printf(“\n\n”);
}
• Output of the Program: This program maintains the telephone
list of the users of the BSNL in Gwalior City!!!
Please enter how many records we want in the list:
2
Please enter the information of the users:
Name: Nikhat Khan
Telephone Number: 462003
Profession: Lecturer
Address: C/o. Rajendra Jain, Shinde Ki Chhawni, Lashker, Gwl.
Name: Alok Jain
Telephone Number: 230091
Profession: Student
Address: Hanuman Ghati, Lashker, Gwalior
List of the Users
###################
Name: Nikhat Khan
Telephone Number: 462003
Profession: Lecturer
Address: C/o. Rajendra Jain, Shinde Ki Chhawni, Lashker, Gwl.
Name: Alok Jain
Telephone Number: 230091
Profession: Student
Address: Hanuman Ghati, Lashker, Gwalior
54 Data Structure and Algorithm
Exercise
Q.1. Write a function that counts number of vowels in a given text.
Q.2. Write a function that counts number of words in a text and also
counts the words of different types.
Q.3. Write a function that inserts a sub-string in a string somewhere in
the middle.
Q.4. Write a program to access number of students in a class using
pointers to structure.
Q.5. Write a program to implement a structure for the following fields:
– Employee’s Name
– Designation
– Department
– Address
– City
– Telephone Number
Q.6. Write a function that reads a string and transfers its reverse to
another pointer variable.
CHAPTER 2
STACK, QUEUES, AND LIST
CONTENTS
2.1. Introduction....................................................................................... 56
2.2. A Mazing Problem............................................................................. 56
2.3. Static and Dynamic........................................................................... 58
2.4. Queue Introduction........................................................................... 65
2.5. List..................................................................................................... 72
56 Data Structure and Algorithm
2.1. INTRODUCTION
This chapter covers data structures stack, queues, and list along with
their operations. These data structure are discussed in detailed with their
applications. An exercise at the end of chapter is given.
To solve this puzzle, we first start with the source cell and move in a
direction where the path is not blocked. If taken path makes us reach to the
destination then the puzzle is solved else, we come back and change our
direction of the path taken. We are going to implement the same logic in our
code also:
Now, we will make one more matrix of the same dimension to store the
solution. Its elements will also be either 0 or 1. 1 will represent the cells in
our path and rest of the cells will be 0. The matrix representing the solution
is:
Thus, we now have our matrices. Next, we will find a path from the
source cell to the destination cell and the steps we will take are:
58 Data Structure and Algorithm
• Check for the current cell, if it is the destination cell, then the
puzzle is solved.
• If not, then we will try to move downward and see if we can move
in the downward cell or not (to move in a cell it must be vacant
and not already present in the path).
• If we can move there, then we will continue with the path taken
to the next downward cell.
• If not, we will try to move to the rightward cell. And if it is
blocked or taken, we will move upward.
• Similarly, if we can’t move up as well, we will simply move to
the left cell.
• If none of the four moves (down, right, up, or left) are possible, we
will simply move back and change our current path (backtracking).
Thus, the summary is that we try to move to the other cell (down, right,
up, and left) from the current cell and if no movement is possible, then just
come back and change the direction of the path to another cell.
012345678
Initially TR = 9
Initially TL = – 1
Overflow condition TR – TL = 1
In the above implementation, we are implementing two stack in a single
array growing in opposite direction.
• Finding the Average Life Time of an Element in the Stack:
• The time taken for insert or delete is ‘x’ & here is a delay of ‘y’ in
every search operation.
• The life time of an element is considered as time elapsed from
end of push to start of a operation that removes an element from
start.
element: a, b, c, d, e
• Infix, Prefix, and Postfix:
Infix: Binary operations b/w operands
Like a + b
Operand1 operator operand 2
Prefix: Binary operation before the operand
Like + ab
Operator operand1 operand 2
Postfix: Binary operations after the operands.
Like ab +
Operand 1 operand 2 operator
E.g., Infix: A + B × (C + D)/ F + D × E
Prefix: A + B * + CD/ F + D × E
A + B × B + CD/F + D × E
A + / * B + CD F + D × E
+A / * B + CDF + * DE
+ + A/ * B + CDF × DE
Infix: A + B × (C + D)/ F + D × E
62 Data Structure and Algorithm
Postfix: A + B × CD + / F + D × E
A+BCD+*/F+D×E
A+BCD+*F/+DE*
ABCD+*F/+DE*+
Infix: a + b * c – d/e↑ f * g + h
Prefix a + b * c – d / ↑ ef * g +h
= a + *bc – d/ ↑ ef * g + h
= +a * bc – / d ↑ ef * + gh
= – + a * bc / d↑ ef * + g h
= – + a * bv * /
= + – + a * bc * / d ↑ e + gh
Post fix: a b c * + de + ↑ / g * – h +
• Prefix to Postfix Conversion:
In order to convert from prefix to post fix we need:
• Operator followed by
• Two operands
Then convert into postfix.
E.g.: Prefix: * + cd – ba
* cd + – ba
* cd + b a –
cd + ba – *
• Postfix to infix Conversion:
Postfix: ab * cd / – (Two operand followed immediate operator).
Note:
• In order to evaluate infix expression the need to scan in fixes
expression multiple time and we need to jump from the one place
to other place according to the procedure of the operator.
• The procedure must be sequential for the computer and it required
good algorithm.
• The best approach converting infix express to postfix expression
in a single scan and evaluating the post fix expression in a single
scan.
Stack, Queues, and List 63
• Fibonacci Series:
Time Complexity: O(2n)
N 0 1 2 3 4 5 6 7 8 9 10
Fib (n) 0 1 1 2 3 5 8 13 21 34 55
Fib (n) = n, if n = 0 Or n = = 1
Fb (n–1) + Fib (n–2), otherwise.
• Tower of Hanoi: We need to move n discs from left side tower
to right side tower.
Rule:
• Only one disc we can move at a time.
• Large size disc cannot placed on smaller size disc.
E.g.: N = 2
• L → m (1)
• L → R (2)
• M → R (1)
E.g.: n = 3
L → R (1) M → L (1)
L → M (2) M → R (2)
R → M (1) L → R (1)
L → R (3)
E.g.: n = 4
(1) L → M (1) (4) L → M (3) (7) L → M (1) (10) M → L (2)
(2) L → R (2) (5) R → L (1) (8) L → R (4) (11) R → L (1)
(3) M → R (1) (6) R → M (2) (9) M → R (1) (12) M → R (3)
(13) L → M (1) (14) L → R (2) (15) M → R (1)
Program:
Tox (N, L, M, R) T (n)
{
if (n = = 0)
return;
else:
Stack, Queues, and List 65
6 3 7 9 17 19 21
0 1 2 3 4 5 6
F R
Overflow condition: R = =N – 1
Initially
Front = –1;
Rear = –1;
Underflow condition F = = – 1
F = –1 0
R = –1 0 1 2 3 4 5 6
E.g., enqueue operation in the queue.
• Initially check for the overflow condition.
• If it is not overflow, if it is first insertion increment both front and
rear. Otherwise increment only rear pointer and insert the element
with the help of rear pointer.
Enqueue (Q, N, F, R, x) element to be inserted.
{if (R = = N – 1)
{pt (“Overflow condition”);
Return;
}
else if (R = = –1)
{R ++;
F ++;
Stack, Queues, and List 67
Q [O] = x;
}
else {
++R;
Q [R] = x;
}
}
E.g., dequeue operation in the queue.
int dequeue (Q, N, F, R)
int y
{if (F = = – 1)
{pf (“Underflow condition”);
return;
}
else if (F = = R)
{y = Q[F];
F = –1;
R = –1;
}
else {
y = Q [F];
F + +;
}
return y;
}
• Points to Write the Dequeue Program:
• Initially check for the underflow condition.
• If it is not underflow then delete the element using.
• If the front and rear are same reinitialize back to –1, otherwise
increment only front pointer then deleted element.
68 Data Structure and Algorithm
Note:
9 17 19 21
0 1 2 3 4 5 6
F R
F = –1 0 1 2 3
R = –1 0 1 2 3 4 5 6
• In the above implementation of a linear queue when the rear
pointer as reached the eight most point and front pointer is same
where in the middle but still it will show overflow condition.
• Even through empty slots are available the are not efficiently
utilize. To avoid the problem we will implement circular queue.
0 1 2 3 4 5 6
Overflow condition (R+1)/N = = F
Underflow condition = F = = – 1
• Input Restricted Queue: Enqueue operation can be done only
from rear but dequeue can be done both front and rear.
Q 10 20 30 40 50
0 1 2 3 4 5
Dequeue → F Enqueue → R dequeue → R
F ++ R ++ R––
In the above implementation queue property is not satisfied because it is
following FIFO and LIFO.
• Output Restricted Queue:
Q 20 30 40 50
0 1 2 3 4 3
Dequeue → F Enqueue → R Enqueue → F
F++ R++ F––
Dequeue operation is restricted but enqueue operation on can be done
from both front rear.
E.g.:
Q 20 30 40 50
Dequeue → F Enqueue → R Enqueue → F dequeue → R
F++ R++ F–– R–
Enqueue and dequeue operations can be done from both front and rear.
25 30 6 5 40 15
0 1 2 3 4 5
Element: 25, 30, 6, 5, 40, 15
Enqueue:
i = –1, 0
j= –1, 0, 1, 2, 3, 4, 5
Stack, Queues, and List 71
j=j+1
a[o] = x
T.C. = 0[1]
Dequeue: TC: 0(n)
Scan the entire array and find the position of the minimum element:
• y = a [min]
• a [min] = a[j];
• j = j – 1;
• Using Sorted Array:
Enqueue dequeue
TC = 0(n) TC = 0(1)
• Implementing Queue Using Stacks:
Q a b c d e
0 1 2 3 4
Elements: a, b, c, d, e
Q. Write the Psecdo Code for the Enqueue and Dequeue Operation.
Ans:
Enqueue (St, x)
{push (st, x);
}
int dequeue (S1, S2)
{
if (S2 is not empty)
{return pop (S2);
}
else if (S1 is empty)
{pf (“Queue is empty”)
Exit ( );
}
else
while (S1 is not empty)
72 Data Structure and Algorithm
{x = pop (s1);
push (S2, x);
}
return pop (s2);
}
}
2.5. LIST
A linked list is a linear data structure, in which the elements are not stored at
contiguous memory locations. The elements in a linked list are linked using
pointers as shown in Figure 2.6.
temp = temp->next;
}
temp->next = newNode;
• Add to Middle:
• Allocate memory and store data for new node;
• Traverse to node just before the required position of new node;
• Change next pointers to include new node in between.
struct node *newNode;
newNode = malloc(sizeof(struct node));
newNode->data = 4;
struct node *temp = head;
for(int i=2; i < position; i++) {
if(temp->next != NULL) {
temp = temp->next;
}
}
newNode->next = temp->next;
temp->next = newNode;
• Deletion from a Linked List: You can delete either from
beginning, end or from a particular position.
• Delete from Beginning:
• Point head to the second node
head = head->next;
• Delete from End:
• Traverse to second last element
• Change its next pointer to null
struct node* temp = head;
while(temp->next->next!=NULL){
temp = temp->next;
}
temp->next = NULL;
• Delete from Middle:
Stack, Queues, and List 77
p = p → next;
count ++;
}
}
return count;
}
• Q.3. Write a program to insert new node in the beginning of the
linked list.
Ans:
insert at begin (node * head)
{node * temp;
temp = (node*) malloc (sized(node));
if (temp = = NULL)
exit ( );
temp → next = NULL;
print f (“Enter data element”);
Scanf (“%d,” & temp → data);
if (head = = NULL)
head = temp;
else {
temp → next = head;
head = temp
}
Temp = NULL;
}
• Q.4. Write a program to insert new node at the end of the given
linked list.
Ans:
Insertatend (node * head)
{node * temp
Temp = (node*) malloc (size of (node))
80 Data Structure and Algorithm
if (temp = = NULL)
exit (O);
print f(“Enter the data value”);
Scanf (“%d” & temp → data);
if (head = = NULL)
head = temp;
else {
node * p = head;
while (p → next ! = NULL)
{p = p → next;
}
p → next = temp;
}
p=NULL;
temp = NULL;
}
• Q.5. Write a program to insert the new node at the given position.
Ans:
Insertatpos (node * head, int pos)
{int length, k=1;
length = list length (head);
if (pos ≤ O || POS > length +1)
printf(“Invalid position”);
else if (pos = = 1)
insert at begin (head);
else if (pos = = length + 1)
insert at end (head);
else {
node * p = head;
node * temp = (node *) malloc (sized of (mode));
temp → next = NULL;
Stack, Queues, and List 81
if (head = = NULL)
{head = temp;
Head → next = head; temp = NULL
}
else (node * p = head;
while (p → next ! = head)
{p = p → next;
}
P → next = temp
temp → next = head;
p = NULL
temp = NULL;
}
}
• Q.14. Write a program to delete the last node in the CSLL.
Ans:
delete At end CSLL (node * head)
{if (head = = NULL)
{pf (“list is empty”);
return;
}
if (head → next = = head)
{free (head);
Head = NULL;
}
else (node * p, * q = head;
while (q→ next ! = head)
{
p = q;
q = q → next;
}
Stack, Queues, and List 87
P → next = head;
free (q);
q = null; p = Null;
}
}
• Q.15. Write a program to delete the first node of given CSL.
Ans:
delete At Begin CSLL (nod * head)
if (head = = NULL)
{pf (“List is empty”);
Return;
}
if (head → next = = head)
{free (head);
head = NULL;
}
else
{node * p, * q = head;
p = head → next;
while (q → next ! = head)
{q = q → next;
}
q → next = p;
head = p;
Free (p);
Free (q);
P = NULL; q = NULL;
}
}
CHAPTER 3
TREES
CONTENTS
3.1. Introduction....................................................................................... 90
3.2. Basic Concepts.................................................................................. 90
3.3. Tree................................................................................................... 91
3.4. Binary Tree........................................................................................ 92
3.5. Traversals Operation of a Binary Tree............................................... 110
3.6. Threaded Binary Tree....................................................................... 117
3.7. Binary Expression Tree..................................................................... 119
3.8. Conversion of General Tree to Binary Tree....................................... 120
3.9. Applications of Tree......................................................................... 122
3.10. Sequential or Linear Search........................................................... 127
3.11. Binary Search................................................................................ 133
3.12. Height Balanced Tree..................................................................... 140
3.13. Weight Balanced Tree.................................................................... 141
3.14. Multiway Search Trees................................................................... 142
3.15. Digital Search Trees....................................................................... 143
3.16. Hashing......................................................................................... 144
90 Data Structure and Algorithm
3.1. INTRODUCTION
This chapter covers trees with its basic terminology, formal definition of the
tree and types of the tree. In case of binary tree, chapter covers its definition,
representation, operations, traversal of binary tree, threaded binary trees,
conversion of general tree to binary tree and binary expression tree. It also
covers application of trees, searching technique like- sequential search,
binary search, height balanced trees, weight balanced trees and digital
search trees. Searching technique hashing with various hashing functions
and collisions handling techniques are also covered in this chapter.
0
1
2
3.3. TREE
Definition: Let us formally define a tree. A tree(T) is a non-empty finite
collection of nodes or vertices, such that:
• There is one specially designated vertex or node called root of
the tree(T),
• The remaining nodes are partitioned into a collection of sub-trees
T1, T2,T3,…,Tn each of which is again a tree.
92 Data Structure and Algorithm
0
1
2
3
Figure 3.4. A complete binary tree.
94 Data Structure and Algorithm
0
1
2
3
Level 0 1
Level 1 2 3
Level 2 4 5 6 7
Level 3 8 9
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
B C D E F H I . . . . K L . .
5 – – –
6 D 0 0
7 J 9 11
8 – – –
9 H 0 10
10 I 0 0
11 K 0 0
Figure 3.12 shows the logical view of the linked representation of a
binary tree shown in Figure 3.11. ROOT will contain the location of the
parent node of binary tree. If any sub-tree is empty, then the corresponding
pointer will contain the null value. If the binary tree itself is empty, then
ROOT will contain the null value.
pointer[right] = NULL,
pointer[info] = info
c. [Test for the left sub-tree]
If(info<pointer[info])then call recursively binary_insert function for left
sub-tree
Set pointer[left] = binary_insert(pointer[left], info)
d. [Test for the right sub-tree]
If(info>pointer[info])then call recursively binary_insert function for
right sub-tree
Set pointer[right] = binary_insert(pointer[right], info)
e. [Otherwise item is duplicate]
write ‘item is duplicate’
f. return(pointer)
g. End.
B. Equivalent Function in C:
BTree *binary_insert(BTree *pointer, int info)
{
/*Check whether the tree is empty */
if(pointer==NULL)
{
pointer =(BTree)malloc(sizeof(BTree));
pointer->left = NULL;
pointer->right = NULL;
pointer->info = info;
}
else /*Test for the left child*/
if(info < pointer->info)
pointer->left = binary_insert(pointer->left,info);
else /*Test for the right child*/
if(info >pointer->info)
pointer->right = binary_insert(pointer->right,info);
else /*Duplicate entry*/
Trees 101
printf(“Duplicate entry\n”);
return(pointer);
}
• Searching in a Binary Search Tree: To search a particular node
in a binary search tree. We start the search from the root node,
and compare the root node with the searched node. If the values
are equal the search is said to be successful and searched node
is found in the tree. If the searched value is less than the value
in the root node, then it must be in the left sub-tree and if there
is no left sub-tree, the value is not in the tree, i.e., the search is
unsuccessful. If there is a left sub-tree, then it is searched in the
same way. Similarly, if the searched value is greater than the value
in the root node, the right sub-tree is searched. Figure 3.14 shows
the path(in shaded line) for searching of 57 in binary search tree.
(b)
(c)
(c)
(d)
Figure 3.16. Deletion of node 70.
104 Data Structure and Algorithm
35
Set parent[right]=NULL
return(pointer)
i. [Deletion when node contains only one child]
If(case==2) then
[Node is a left child]
If(parent[left]=pointer)then
If(pointer[left]==NULL)then
Set parent[left]=pointer[right]
else
Set parent[left]=pointer[left]
else
[Node is a right child]
If(parent[right]=pointer)then
If(pointer[left]==NULL)then
Set parent[right]=pointer[right]
else
Set parent[right]=pointer[left]
return(pointer)
j. [Deletion when node contains two childs]
If(case==3) then
[Find the in order successor of the node]
Set pointer1=pointer[right]
[Check right sub-tree is not empty]
If(pointer1!=NULL)then
Repeat while(pointer1[left]!=NULL)
[Move to the left most end]
pointer1=pointer1[left]
Set item=pointer1[info]
Call function binary_delete(pointer,item) for deletion of inorder successor
[Replace the deleted node with the inorder successor of the node]
Repeat while ((pointer !=NULL) and (flag==0))
Trees 107
flag=1;
}
/*When node does not exist*/
if(flag==0)
{
printf(“Node does not exist in the tree\n”);
exit(0);
}
else /*Decide the case of deletion*/
{
if(pointer->left ==NULL) && (pointer->right==NULL)
/*Node has no child*/
case =1;
else
if(pointer-> !=NULL) && (pointer->right!=NULL)
/*Node contains both the child*/
case =3;
else
/*Node contains only one child*/
case=2;
}
/* Deletion of node based on cases */
if(case==1)
{
/*Deletion when node has no child*/
if(parent->left=pointer)
parent->left=NULL;
else
parent->right=NULL;
return(pointer);
}
Trees 109
else
/*Deletion when node contains only one child*/
if(case==2)
{
/*Node is a left child*/
if(parent->left=pointer)
{
if(pointer->left==NULL)
parent->left=pointer->right;
else
parent->left=pointer->left;
}
else /*Node is a right child*/
if(parent->right=pointer)
{
if(pointer->left==NULL)
parent->right=pointer->right;
else
parent->right=pointer->left;
}
return(pointer);
}
else
/*Deletion when node contains two child*/
if(case==3)
{
/*Find the in order successor of the node*/
pointer1=pointer->right;
/*Check right sub-tree is not empty*/
if(pointer1!=NULL)
{
110 Data Structure and Algorithm
while(pointer1->left!=NULL)
/*Move to the left most end*/
pointer1=pointer1->left;
}
item=pointer1[info];
/* Delete inorder successor of the node*/
binary_delete(pointer,item);
/*Replace the deleted node with the inorder successor of the node*/
while((pointer!=NULL) && (flag==0))
{
if(info <pointer->info)
pointer = pointer->left;
else
if(info >pointer->info)
pointer = pointer->right;
else
{
flag=1;
pointer[info]= item;
}
}
return(pointer);
}
}
printf(“%3c,”pointer->info);
Preorder(pointer->left);
Preorder(pointer->right);
}
}
For example the level by level traversal of the binary tree given in Figure
3.19 would result in the following string: FCJBDKHI.
else
printf(“Duplicate entry\n”);
return(pointer);
}
void Preorder(BTree * pointer)
{
if (pointer!=NULL)
{
printf(“%3c,”pointer->info);
Preorder(pointer->left);
Preorder(pointer->right);
}
}
void Inorder(BTree * pointer)
{
if (pointer != NULL)
{
Inorder(pointer->left);
printf(“%3c,”pointer->info);
Inorder(pointer->right);
}
}
void Postorder(BTree * pointer)
{
if (pointer!= NULL)
{
Postorder(pointer->left);
Postorder(pointer->right);
printf(“%3c,”pointer->info);
}
}
Trees 117
When tree does not have a header node then the left pointer of the
first node and the right pointer of the last node will contain the null value.
Otherwise, it will point to the header node. Figure 3.22 shows two-way
inorder threading with header node.
the binary expression tree. Figure 3.23 shows the binary expression tree of
the arithmetic expression:
E = (B–C) + (E/F) × D
A linear search does not depend for its success on the items being
searched already being in any particular order. The value being sought will
either be equal to one of the ones already in the array, or it will not. If it
is, the index number of the position at which it is found can be returned.
Otherwise, some indication that the search has failed must be passed back.
Let us consider the following list of numbers:
11 34 23 45 38 10 56 36 27 67
• Search the Element 38: In this technique, the searched item is
compared with all the items of the array one by one, i.e., element
38 is compared to the first element 11, which is not equal to 38.
Now, 38 is compared with next element, i.e., 34. It is also not
equal to 38. This process continues till we reach the end of the
list or the searched element is found in the list. The element 38
is found in the list at position 4. So, the search is successful and
returns the position of the element within the list, i.e., 4.
• Search the Element 40: In this technique, the searched item is
compared with all the items of the array one by one, i.e., element
40 is compared to the first element 11, which is not equal to 40.
Now, 40 is compared with next element, i.e., 34. It is also not
equal to 40. This process continues till we reach the end of the
list or the searched element is found in the list. The element 40 is
not found in the list. So, the search is unsuccessful and returns the
element, which is not found in the list.
The following is the algorithm, which implements the above processing
of searching:
A. Algorithm: Let LIST be a linear array with n elements and
ITEM is a given element of information. This algorithm finds
the position(POS) of ITEM in LIST, if the search is successful or
sets POS=0. If the searched item is not found in the list, it means
search is unsuccessful. Following are the steps for sequential
search algorithm:
a. [Initialize counter]
Set (counter) i=1, POS=0
b. [Search element]
Repeat Step (c) and (d) while(POS==0 || i<=n)
c. [Compare searched ITEM with each element of the LIST] If
ITEM == LIST[i] then the search is successful and print the
Trees 129
/* search_sequential.c*/
#include<stdio.h>
void sequential_search(int[],int,int);
void main()
{
int i,n,LIST[100],ITEM;
printf(“This program search the specified ITEM in the LIST and return the
position(POS) of the ITEM, (if found) using sequential search!!!\n”);
printf(“Please enter the number of elements in the LIST:\n”);
scanf(“%d,”&n);
printf(“Enter the element of the LIST:\n”);
for (i=1;i<=n;i++)
{
scanf(“%d,”&LIST[i]);
}
printf(“Element to be searched:\n”);
scanf(“%d,”&ITEM);
printf(“Entered elements in the LIST are:\n”);
for (i=1;i<=n;i++)
{
printf(“%d\t,”LIST[i]);
}
sequential_search(LIST,n,ITEM);
}
void sequential_search(int LIST[], int n, int ITEM)
{
int i=1, POS;
POS = 0;
while((i<=n) || (POS==0))
{
if(ITEM == LIST[i])
Trees 131
{
POS = i;
printf(“\nThe search item %d is found in the LIST at position %d.\n,”ITEM,
POS);
i = i +1;
continue;
}
else
i = i +1;
if(i==n)
break;
}
if(POS == 0)
printf(“\nThe searched item %d is not found in the LIST.\n,”ITEM);
}
D. Output of the Program: This program search the specified
ITEM in the LIST and return the position(POS) of the ITEM, (if
found) using sequential search!!!
Please enter the number of elements in the LIST:
10
Enter the element of the LIST:
12
23
34
45
56
67
78
89
90
23
Element to be searched:
132 Data Structure and Algorithm
23
Entered elements in the LIST are:
12 23 34 45 56 67 78 89 90 23
The search item 23 is found in the LIST at position 2.
The search item 23 is found in the LIST at position 10.
This program search the specified ITEM in the LIST and return the
position(POS) of the ITEM, (if found) using sequential search!!!
Please enter the number of elements in the LIST:
5
Enter the element of LIST:
12
23
21
34
43
Element to be searched:
29
Entered elements in the LIST are:
12 23 21 34 43
The searched item 29 is not found in the LIST.
E. Analysis of Sequential Search Method: Let’s examine how
long it will take to find an item matching a key in the LIST we
have discussed so far. We are interested in:
i. the average time;
ii. the worst-case time;
iii. the best possible time.
However, we will generally be most concerned with the worst-case
time as calculations based on worst-case times can lead to guaranteed
performance predictions. Conveniently, the worst-case times are generally
easier to calculate than average times.
If there are n items in our LIST, whether it is stored as an array or as a
linked list, then it is obvious that in the worst case, when there is no item in
the LIST with the desired key, then n comparisons of the key with keys of
Trees 133
Print ‘search is successful and item is found in the LIST at position POS’
i. End.
B. Equivalent Function in C
void binary_search(int LIST[], int n, int ITEM)
{
int BEG,END,POS,MID;
BEG=1;
END=n;
POS = 0;
while((BEG<=END) && (POS==0))
{
MID = (BEG+END)/2;
if(ITEM == LIST[MID])
{
POS = MID;
break;
}
else
if(ITEM < LIST[MID])
END = MID – 1;
else
BEG = MID + 1;
}
if(POS == 0)
printf(“The searched item %d is not found in the LIST.\n,”ITEM);
else
printf(“The searched item%d is found in the LIST at position %d.\n,”ITEM,
POS);
}
C. Implementation of Binary Search Function: The following
program search_binary.c implements the sequential search
function using the sorted array LIST:
Trees 137
/*search_binary.c*/
#include<stdio.h>
void binary_search(int[],int,int);
void main()
{
int i,n,LIST[100],ITEM;
printf(“This program searches the specified ITEM in the sorted LIST and
returns the position(POS) of the ITEM, (if found) using binary search!!!\n”);
printf(“Please enter the number of elements in the LIST:\n”);
scanf(“%d,”&n);
printf(“Enter the element of the LIST in ascending order:\n”);
for (i=1;i<=n;i++)
{
scanf(“%d,”&LIST[i]);
}
printf(“Element to be searched:\n”);
scanf(“%d,”&ITEM);
printf(“Entered elements in the LIST are:\n”);
for (i=1;i<=n;i++)
{
printf(“%d\t,”LIST[i]);
}
binary_search(LIST,n,ITEM);
}
void binary_search(int LIST[], int n, int ITEM)
{
int BEG,END,POS,MID;
BEG=1;
END=n;
POS = 0;
while((BEG<=END) && (POS==0))
138 Data Structure and Algorithm
{
MID = (BEG+END)/2;
if(ITEM == LIST[MID])
{
POS = MID;
break;
}
else
if(ITEM < LIST[MID])
END = MID – 1;
Else
BEG = MID + 1;
}
if(POS == 0)
printf(“The searched item %d is not found in the LIST.\n,”ITEM);
else
printf(“The searched item %d is found in the LIST at position %d.\n,”ITEM,
POS);
}
D. Output of the Program: This program searches the specified ITEM
in the sorted LIST and returns the position(POS) of the ITEM, (if found)
using binary search!!!
Please enter the number of elements in the LIST:
10
Enter the element of the LIST in ascending order:
11
12
23
34
45
56
67
Trees 139
78
89
90
Element to be searched:
56
Entered elements in the LIST are:
11 12 23 34 45 56 67 78 89 90
The searched item 56 is found in the LIST at position 6.
This program searches the specified ITEM in the sorted LIST and returns
the position(POS) of the ITEM, (if found) using binary search!!!
Please enter the number of elements in the LIST:
5
Enter the element of the LIST in ascending order:
12
23
34
45
56
Element to be searched:
33
Entered elements in the LIST are:
12 23 34 45 56
The searched item 33 is not found in the LIST.
E. Analysis of Binary Search Method: Each step of the algorithm
divides the block of items being searched in half. We can divide a
set of n items in half at most log2 n times. Thus the running time
of a binary search is proportional to log n and we say this is a
O(log n) algorithm.
F. Comparison between Sequential and Binary Search: Binary
search requires a more complex program than our sequential
search and thus for small n it may run slower than the sequential
search. However, for large n,
lim log n
140 Data Structure and Algorithm
=0
n->∞ n
Thus at large n, log n is much smaller than n, consequently an O(log n)
algorithm is much faster than an O(n) one (Figure 3.27).
When the tree is set up, the nodes with the highest probability of access
are placed at the top. That way the nodes that are most likely to be accessed
have the lowest search time. The tree is balanced, if the weights in the right
and left sub trees are as equal as possible.
The average length of a search in a weighted tree is equal to the sum of:
probability × depth for every node in the tree
The tree is set up with the highest weighted node at the top of the tree
or sub-tree. The left sub-tree contains nodes whose data values are less than
the current node, and the right sub-tree contains nodes that have data values
greater than the current data value.
3.16. HASHING
It is a searching technique, which is independent of the number n of elements
in the collection of data.
k: 356942781
parts: k1 = 356 k2 = 942 k3 = 781
Fold shifting: k1 = 356 k2 = 249 k3 = 781
356+249+781 =1386
Fold boundary: k1 = 653 k2 = 942 k3 = 187
653 + 942 + 187 = 1782
This method is also useful in converting multiword keys into a single word
so that it can be used by the other hashing function.
[8] – 18 18 18
[9] 49 49 49 49
The problem with linear probing is that records tend to get cluste-red
around each other, i.e., once an element is placed in the hash table the
chances of it’s adjacent element being filled are doubled (i.e., it can either be
filled by a collision or directly). If two adjacent elements are filled then the
chances of the next element being filled is three times that for an element
with no neighbor.
2. Quadratic Probing: It is a collision resolution method that
eliminates the primary clustering problem of linear probing. In
quadratic probing, if there is a collision we first try and insert an
element in the next adjacent space (at a distance of +1). If this is
full we try a distance of 4 (22) then 9 (32) and so until we find an
empty element. The full index function is of the form:
(h + i2) % HashTableSize for i = 0, 1, 2, 3, …
where; h is the initial hashed key value.
We take the modulus of the result so the search can wrap around to the
beginning of the table. Even so not all the locations in a table may be able
to be reached (especially if the table size is a power of 2). This means we
may not be able to insert a value even though the table is not full. Generally
though, in linear and quadratic probing, the hash table size is deliberately
kept considerably larger than the number of expected keys, otherwise the
performance of hashing becomes too slow (as the table becomes fuller more
collisions occur and more probing is required to insert and retrieve elements)
(Table 3.5).
For example,
As before insert: 49 18 89 48, Hash table size = 10
[5] – – – –
[6] – – – –
[7] – – – –
[8] – 18 18 18
[9] 49 49 49 49
3. Double Hashing: Another method of probing is to use a second
hash function to calculate the probing distance. For example, we
define a second hash function Hash2(Key) and we use the return
value as the probe value. If this results in a collision we try a
distance of 2 * Hash2(Key), then 3 * Hash2(Key) and so on. A
common second hash function is:
Hash2(Key) = R – (Key % R)
where; R is a prime number smaller than the hash table size. The full index
function is then of the form:
(h + i*(R – (Key % R)) % HashTableSize for i = 0, 1, 2, 3, …
where; h is the initial hashed key value.
4. Rehashing: If the table gets too full, the running time for the
operations will start taking too long and inserts might fail with
quadratic probing.
The standard solution in this case is to build an entirely new hash table
approximately twice the size of the original, calculate a new hash value for
each key and then insert all keys into the new table (then destroying the old
table). This is known as reorganization or rehashing.
5. Chaining: In this method, we keep a linked list of all elements
that hash to the same value. The hash table itself becomes an
array of pointers to list nodes instead of an array of elements that
hold actual records. When collisions occur in chaining, elements
are simply added to the appropriate linked list.
For example,
Insert: 0 1 4 9 16 25 36 49 64 81,
Hash table size = 10, so
Trees 149
void main()
{
int i;
HashTableCreate();
for(i=1;i<200;++i) // Insert values from 1–199
{
HashTableInsert(i);
}
HashTablePrint(); // Print out all of the Hash Table
for(i=50;i<=90;++i) // Remove keys 50–90
{
HashTableDelete(i);
}
HashTablePrint(); // Print out Hash table
HashTableDestroy(); // Destroy the Hash Table
}
void HashTableCreate()
{
int i;
for(i=0;i<HTABLESIZE;++i)
{
HashTable[i]=0;
}
}
void HashTableDestroy()
{
int i;
struct Node *p,*temp;
for(i=0;i<HTABLESIZE;++i)
{
for(p=HashTable[i];p!=0;)
Trees 151
{
temp=p;
p=p->Next;
free(temp);
}
}
}
int HashTableInsert(int data) // = –1 on failure, =0 if ok
{
int ind;
struct Node *nw;
nw=(struct Node *)malloc(sizeof(struct Node));
if(nw==0)
{
return –1;
}
nw->Data=data;
ind=HashFunction(data);
nw->Next=HashTable[ind];
HashTable[ind]=nw;
return 0;
}
struct Node *HashTableFind(int data) // search return data node
{
struct Node *p;
for(p=HashTable[HashFunction(data)];p!=0;p=p->Next)
{
if(p->Data==data)
{
return p;
}
152 Data Structure and Algorithm
}
return 0;
}
int HashTableDelete(int data) // =0 ok, = –1 on fail
{
int ind;
struct Node *p,*temp;
ind=HashFunction(data);
if((p=HashTable[ind])==0)
{
return –1;
}
if(p->Data==data)
{
HashTable[ind]=p->Next;
free(p);
return 0;
}
for(; p->Next!=0; p=p->Next)
{
if(p->Next->Data==data)
{
temp=p->Next;
p->Next=temp->Next;
free(temp);
return 0;
}
}
return –1;
}
int HashFunction(int data)
Trees 153
{
return data%HTABLESIZE; // Simple Function
}
void HashTablePrint() // Print all elements in table
{
int i;
for(i=0;i<HTABLESIZE;++i)
{
struct Node *p;
printf(“Slot %d:,”i);
for(p=HashTable[i];p!=0;p=p->Next)
{
printf(“ %d,”p->Data);
}
printf(“\n”);
}
printf(“\n”);
}
Exercise
• Q.1. What is the purpose of writing the more complicated code to
do binary searches, when a linear one will not only find the item
if it is there, but does not even require the data to be sorted in the
first place?
• Q.2. On your system, for what list length is a binary search more
time efficient than a linear search?
• Q.3. Write an algorithm to display the elements of a binary tree
in level order, i.e., list the element in the root, followed by the
elements in depth 1, then the elements at depth 2, and so on.
• Q.4. An in order threaded binary tree is given. Write an algorithm
to find the pre order and post order threaded binary tree.
154 Data Structure and Algorithm
• Q.13. Give the pre order, inorder, post order, and level-order
traversals for the following trees:
Trees 155
CONTENTS
4.1. Introduction..................................................................................... 158
4.2. Sorting............................................................................................. 158
4.3. Complexity of the Algorithm............................................................ 202
158 Data Structure and Algorithm
4.1. INTRODUCTION
This chapter covers various sorting techniques like- bubble sort, insertion
sort, selection sort, quick sort, merge sort, address calculation sort and
heap sort. These techniques are discussed with the help of array of integers.
Complexity of the algorithm is also discussed at the end of the unit. An
exercise at the end of chapter is given.
4.2. SORTING
Sorting is one of the most important operations performed by computers. In
the days of magnetic tape storage before modern data-bases, it was almost
certainly the most common operation performed by computers as most
“database” updating was done by sorting transactions and merging them
with a master file. It’s still important for presentation of data extracted from
databases: most people prefer to get reports sorted into some relevant order
before wading through pages of data.
The basic premise behind sorting an array is that, its elements start out
in some (presumably) random order and need to be arranged from lowest to
highest. If the number of items to be sorted is small, a reader may be able to
tell at a glance what the correct order ought to be. If there are a large number
of items, a more systematic approach is required. To do this, it is necessary
to think about what it means for an array to be sorted. It is easy to see that
the list 1, 5, 6, 19, 23, 45, 67, 98, 124, 401 is sorted, whereas the list 4, 1,
90, 34, 100, 45, 23, 82, 11, 0, 600, 345 is not. The property that makes the
second one “not sorted” is that, there are adjacent elements that are out of
order. The first item is greater than the second instead of less, and likewise
the third is greater than the fourth and so on.
Once this observation is made, it is not very hard to devise a sort that
precedes by examining adjacent elements to see if they are in order, and
swapping them if they are not. The following are the methods, which can be
used for performing sorting:
• Bubble sort;
• Selection sort;
• Insertion sort;
• Quick sort;
• Merge sort;
Sorting Algorithms 159
There are two ways in which the sort can terminate with everything in
the right order. It could complete by reaching the n–1th pass and placing
the second smallest item in its correct position. Alternately, it could find
on some earlier pass that nothing needs to be swapped. That is, all adjacent
pairs are already in the correct order. In this case, there is no need to go on
to subsequent passes, for the sort is complete already.
If the list started in sorted order, this would happen on the very first pass.
If it started in reverse order, it would not happen until the last one.
When this sort was tested, statements were included to print the array
after each comparison, and to print the number of swaps on each pass. The
original data is given first, and the items that are compared are emphasized.
234 77 0 113 404 94 900 113 15 300 13 135
Pass number 1
77 234 0 113 404 94 900 113 15 300 13 135
77 0 234 113 404 94 900 113 15 300 13 135
77 0 113 234 404 94 900 113 15 300 13 135
77 0 113 234 404 94 900 113 15 300 13 135
77 0 113 234 94 404 900 113 15 300 13 135
77 0 113 234 94 404 900 113 15 300 13 135
77 0 113 234 94 404 113 900 15 300 13 135
77 0 113 234 94 404 113 15 900 300 13 135
77 0 113 234 94 404 113 15 300 900 13 135
77 0 113 234 94 404 113 15 300 13 900 135
77 0 113 234 94 404 113 15 300 13 135 900
Swaps on this pass = 9
Pass number 2
0 77 113 234 94 404 113 15 300 13 135 900
0 77 113 234 94 404 113 15 300 13 135 900
0 77 113 234 94 404 113 15 300 13 135 900
0 77 113 94 234 404 113 15 300 13 135 900
0 77 113 94 234 404 113 15 300 13 135 900
0 77 113 94 234 113 404 15 300 13 135 900
0 77 113 94 234 113 15 404 300 13 135 900
Sorting Algorithms 161
array[i]=array[i+1];
array[i+1]=temp;
}
}
}
}
void Input(int array[],int n)
{
int i;
printf(“Please enter the number of the array:\n”);
for (i=0;i<n;i++)
scanf(“%d,”&array[i]);
printf(“Array before sorting: “);
for(i=0;i<n;++i)
printf(“%d,”array[i]);
printf(“\n”);
}
void Print(int array[],int n)
{
int i;
printf(“Array after sorting: “);
for(i=0;i<n;++i)
{
printf(“%d,”array[i]);
}
printf(“\n”);
}
D. Output of the Program: !!!This program sorts the array of
integers using bubble sort algorithm!!!
Please enter how many numbers are there in the array:
10
Please enter the number of the array:
166 Data Structure and Algorithm
12
21
32
31
45
34
56
54
67
65
Array before sorting: 12 21 32 31 45 34 56 54 67 65
Array after sorting: 12 21 31 32 34 45 54 56 65 67
E. Analysis: The best case involves performing one pass, which
requires n–1 comparisons in the outer loop. Hence, the best case
is O(n). In worst case, array is in reverse order and the inner loop
uses the maximum number of comparisons n–1. Hence, the worst
case is O(n2). The average case is more difficult to analyze. The
number of comparisons in the inner loop is (n–1)/2. Hence, the
average case is O(n2).
Pass number 2
0 13 234 113 404 94 900 115 15 300 77 135
Pass number 3
0 13 15 113 404 94 900 115 234 300 77 135
Pass number 4
0 13 15 77 404 94 900 115 234 300 113 135
Pass number 5
0 13 15 77 94 404 900 115 234 300 113 135
Pass number 6
0 13 15 77 94 113 900 115 234 300 404 135
Pass number 7
0 13 15 77 94 113 115 900 234 300 404 135
Pass number 8
0 13 15 77 94 113 115 135 234 300 404 900
Pass number 9
0 13 15 77 94 113 115 135 234 300 404 900
Pass number 10
0 13 15 77 94 113 115 135 234 300 404 900
Pass number 11
0 13 15 77 94 113 115 135 234 300 404 900
A. Algorithm: The steps to be taken are as follows:
a. Initialize k = n–1
b. Repeat steps (c) to (g) while(k>0)
c. Initialize pos = 0, i = 1
d. Repeat steps (e) to (f) while(i<=k)
e. [Compare the i’th element to the pos element]
If(array[i] > array[pos]) then
f. Set pos = i
g. Set temp=array[pos];
array[pos]=array[k];
array[k]=temp;
h. End.
168 Data Structure and Algorithm
B. Equivalent C Function:
void SelectionSort(int array[],int n)
{
int i,k,pos,min,temp;
for(k=0;k<n;k++)
{
min = array[k];
pos=k;
for(i=k+1;i<n;++i)
{
if(array[i]<min)
{
min = array[i];
pos=i;
}
}
temp=array[k];
array[k]=array[pos];
array[pos]=temp;
}
}
C. Implementation of Selection Sort Function: The following
program sort_selection.c implements the selection sort function
using the array of integers:
/*sort_selection.c */
#include <stdio.h>
#include <stdlib.h>
#define N 100
void Input(int array[],int n);
void SelectionSort(int array[],int n);
void Print(int array[],int n);
void main()
Sorting Algorithms 169
{
int n,array[N];
printf(“!!!This program sorts the array of integers using selection sort
algorithm!!!\n”);
printf(“Please enter how many numbers are there in the array:\n”);
scanf(“%d,”&n);
Input(array,n);
SelectionSort(array,n);
Print(array,n);
}
void SelectionSort(int array[],int n)
{
int i,k,pos,min,temp;
for(k=0;k<n;k++)
{
min = array[k];
pos=k;
for(i=k+1;i<n;++i)
{
if(array[i]<min)
{
min = array[i]; //Find the smallest value
pos=i;
}
}
temp=array[k];
array[k]=array[pos];
array[pos]=temp;
}
}
170 Data Structure and Algorithm
900
113
15
300
13
135
5
Array before sorting: 234 77 113 404 94 900 113 15 300 13 135 5
Array after sorting: 5 13 15 77 94 113 113 135 234 300 404 900
E. Analysis: During the first pass, in which the record with the
smallest key is found, n–1 records are compared. In general
for i’th pass of the sort, n-i comparisons are required. The total
number of comparisons is therefore, n(n–1)/2. Hence, the number
of comparisons is proportional to O(n2).
scanf(“%d,”&array[i]);
printf(“Array before sorting: “);
for(i=0;i<n;++i)
printf(“%d,”array[i]);
printf(“\n”);
}
void Print(int array[],int n)
{
int i;
printf(“Array after sorting: “);
for(i=0;i<n;++i)
{
printf(“%d,”array[i]);
}
printf(“\n”);
}
D. Output of the Program: !!!This program sorts the array of
integers using insertion sort algorithm!!!
Please enter how many numbers are there in the array:
12
Please enter the number of the array:
113
77
50
113
114
900
113
15
300
13
135
Sorting Algorithms 175
1
Array before sorting:
113 77 50 113 114 900 113 15 300 13 135 1
Array after sorting:
1 13 15 50 77 113 113 113 114 135 300 900
E. Analysis: This sorting method is frequently used when the
array size is small and linear search is about as efficient as the
binary search. The best case requires array to be in order, so
that it involves performing only one pass, which requires n–1
comparisons in the outer loop. Hence, the best case is O(n). The
worst case is there, if array is in reverse order and the inner loop
uses the maximum number of comparisons n–1. Hence, the worst
case is O(n2). The average case is more difficult to analyze. The
number of comparisons in the inner loop is (n–1)/2. Hence, the
average case is O(n2).
16 7 9 5 2 18 8 53 1 44 17
The underscore marks the two that were swapped and also the places
where counting was suspended in the forward and backward scans.
Continuing, the next two that must be swapped because they are in the
wrong sub-list are item #6 (18) and item #9 (1) so the list becomes:
16 7 9 5 2 1 8 53 18 44 17
The next item found that is greater than 16 is item #8 (53), but at this
point, the count from the right passes with the one from the left (at the
arrow) without finding another item less than the pivot value. So, there are
no more swaps to make in this pass, and the scan has now found the correct
place to put the pivot item (at position #7):
16 7 9 5 2 1 8 53 18 44 17
Rather than move everything down and insert it there, observe that the
lower items are out of order any way and can be re-positioned later, so it will
do to simply swap the pivot item with item #7. This produces:
8 7 9 5 2 1 16 53 18 44 17
The list is written with the 16 isolated, inverted, and separating two
sub-lists so as to emphasize the fact of the partition. The item 16 is now in
the correct position and should never be touched again. Because of the way
in which the correct position for the item 16 was located, everything in the
left sub-list is now less than 16, and everything in the right sub-list is greater
than 16 (hence the name pivot). Thinking recursively, it is now possible to
observe that when the left and right sub-lists are sorted, the entire list will
be sorted.
Repeating for the left sub-list yields:
8 7 9 5 2 1 16 53 18 44 17
8 7 1 5 2 9 16 53 18 44 17
2 7 1 5 8 9 16 53 18 44 17
Sorting Algorithms 177
2 7 1 5 8 9 16 53 18 44 17
2 1 7 5 8 9 16 53 18 44 17
1 2 7 5 8 9 16 53 18 44 17
The left sub-list of the pivot 2 is sorted. When the right sub-list of pivot
2 (two items) is sorted, one has:
1 2 5 7 8 9 16 53 18 44 17
Now, the left sub-list of the last pivot (7) has only one item and it is
sorted. Backing up the recursion chain, the right sub-list of the pivot 8 also
has only one item (9), it is already sorted. Backing up further, the next list to
sort is the right sub-list of the original pivot 16.
1 2 5 7 8 9 16 53 18 44 17
1 2 5 7 8 9 16 17 18 44 53
1 2 5 7 8 9 16 17 18 44 53
1 2 5 7 8 9 16 17 18 44 53
1 2 5 7 8 9 16 17 18 44 53
The last right sub-list of the pivot 18 has only one element and is sorted,
so the entire sort is finished. Note that there were even places where one
or the other of the two sub-lists was empty and also did not need to be
considered.
Having carefully hand-stepped through this sorting method, it is now
possible to produce the code for the quick sort. This code will depart a little
from the previous conventions for sorts in this chapter, in that, it will assume
that it is being called by a client that is already numbering the array [0. n–1].
This assumption is made because the quick sort, being recursive, is its own
major client, and already has the array numbered in that manner when it
calls itself.
Notice, also the treatment of numbers scanned in either direction that
are equal to the pivot. They are left where they are for that scan. Eventually,
they will be shuffled adjacent to this pivot when another sub-list is sorted.
178 Data Structure and Algorithm
{
printf(“%d,”array[i]);
}
printf(“\n”);
}
void QuickSort(int array[],int n)
{
int pivotpos;
if(n<=1)
{
return;
}
pivotpos=Partition(array,n);
QuickSort(array,pivotpos);
QuickSort(array+pivotpos+1,n-pivotpos–1);
}
int Partition(int array[],int n)
{
int pivot,left,right,swap;
pivot=array[0]; // First element is pivot
left=0; right=n–1;
for(;;)
{
while(left<right && array[left]<=pivot)
{
left++;
}
while(left<right && array[right]>pivot)
{
right – –;
182 Data Structure and Algorithm
}
if(left==right)
{
if(array[right]>pivot)
{
left=left–1;
}
break;
}
swap=array[left];
array[left]=array[right];
array[right]=swap;
}
swap=array[0];
array[0]=array[left];
array[left]=swap;
return left;
}
D. Output of the Program: !!!This program sorts the array of
integers using quick sort algorithm !!!
Please enter how many numbers are there in the array:
12
Please enter the number of the array:
16
7
9
44
2
18
8
53
1
Sorting Algorithms 183
5
17
22
Array before sorting: 16 7 9 44 2 18 8 53 1 5 17 22
Array after sorting: 1 2 5 7 8 9 16 17 18 22 44 53
E. Analysis: The best case analysis occurs when, the file is always
partitioned in half. The analysis becomes O(n log n). The worst
case occurs when, at each invocation of the function, the current
list is partitioned into two sub-lists with one of them being empty
or key element is smallest or largest one. The worst case analysis
becomes O(n2). For the average case, analysis becomes O(n log
n).
while((f<=n)&&(w<=last))
{
if(array[f]<=array[w])
{
temp[l]=array[f];
f++;
}
else
{
temp[l]=array[w];
w++;
}
l++;
}
if(f<=n)
{
for(f=f;f<=n;f++)
{
temp[l] = array[f];
l++;
}
}
else
{
for(w=w;w<=last;w++)
{
temp[l]=array[w];
l++;
}
}
for(upper=first;upper<=last;upper++) // copy result back
186 Data Structure and Algorithm
array[upper]=temp[upper];
}
C. Implementation of Merge Sort Function: The following
program sort_merge.c implements the merge sort function using
the array of integers:
/* sort_merge.c */
#include <stdio.h>
#include <stdlib.h>
#define N 100
void Input(int array[],int n);
void MergeSort(int array[],int i,int n);
void Merge(int array[],int f, int l,int n);
void Print(int array[],int n);
void main()
{
int i=0,n,array[N];
printf(“!!!This program sorts the array of integers using merge sort
algorithm!!!\n”);
printf(“Please enter how many number are there in the array:\n”);
scanf(“%d,”&n);
input(array,n);
MergeSort(array,i,n–1);
Print(array,n);
}
void Input(int array[],int n)
{
int i;
printf(“Please enter the number of the array:\n”);
for (i=0;i<n;i++)
scanf(“%d,”&array[i]);
printf(“Array before sorting: “);
for(i=0;i<n;++i)
Sorting Algorithms 187
printf(“%d,”array[i]);
}
void Print(int array[],int n)
{
int i;
printf(“Array after sorting: “);
for(i=0;i<n;++i)
{
printf(“%d,”array[i]);
}
printf(“\n”);
}
void MergeSort(int array[],int i,int n)
{
int mid,first,last;
first=i;
last=n;
if(first!=last)
{
mid = (first+last)/2;
MergeSort(array,first,mid);
MergeSort(array,mid+1,last);
Merge(array,first,mid,last);
}
}
void Merge(int array[],int first,int n,int last)
{
int temp[100];
int f = first;
int w = n+1;
int l = last;
188 Data Structure and Algorithm
int upper;
while((f<=n)&&(w<=last))
{
if(array[f]<=array[w])
{
temp[l]=array[f];
f++;
}
else
{
temp[l]=array[w];
w++;
}
l++;
}
if(f<=n)
{
for(f=f;f<=n;f++)
{
temp[l] = array[f];
l++;
}
}
else
{
for(w=w;w<=last;w++)
{
temp[l]=array[w];
l++;
}
}
Sorting Algorithms 189
Variable Function
n(integer) Size of the hash table
HEAD(pointer) Address of the first record in the sorted
table
HASH_ Vector of pointers representing the hash
TABLE(pointer) table
HASH(integer) Hashing function
RECORD(record) Overflow area record
Sorting Algorithms 191
P←S
S ← LINK(S)
LINK(P) ← NEW
LINK(NEW) ←S
e. [Find first nonempty linked list]
i←1
Repeat while HASH_TABLE[i] = NULL and i<n
i ← i +1
HEAD ← HASH_TABLE[I]
j←i+1
f. [Concatenate the nonempty linked lists]
Repeat while j ≤ n
If HASH_TABLE[j] ≠ NULL then
(Find tail of the linked list)
P ←HASH_TABLE[i]
Repeat while LINK(P) ≠ NULL
P ← LINK(P)
(Link tail of this linked list to the head of the next)
LINK(P) ← HASH_TABLE[j]
i←j
j←i+1
g. End.
B. Analysis: In the best case, the hashing function is uniformly
distributed. The address calculation sort performs in a linear
fashion as each key is assigned to its proper linked list and some
extra work is required to place the key within the linked list. In
such case, the sort is O(n). In the worst case, when all keys are
mapped to the same location, significant work is to be done to
place a key properly within the linked list and the sort is O(n2).
a deletion always causes the next highest element to be moved to the root,
the process of dequeuing will produce an ordered list. The space advantage
of heap sort is obtained by placing each element, we delete from the heap,
at the end of the unsorted section of the list (in a similar way to selection
sort’s strategy of swapping values to the beginning of the list). In this way,
we do not have to create another array to place the sorted elements (merge
sort requires such an array).
However, the first phase of a heap sort involves building the heap from
an unordered list. We can take the advantage of the fact that no deletions will
intervene to create a more efficient insert routine that again reorders a single
array instead of copying from one array to another.
1 2 3 4 5 6 7 8
12 34 17 33 19 22 11 10
We start with the middle element (33) and try to insert it within its own
sub-tree. It is already in a correct position (33 > 10), so we continue by
moving back to 17. As 17 < 22 we move 22 up and replace it with 17 (Figure
4.2):
1 2 3 4 5 6 7 8
12 34 22 33 19 17 11 10
1 2 3 4 5 6 7 8
34 33 22 12 19 17 11 10
1 2 3 4 5 6 7 8
33 19 22 12 10 17 11 34
We would now take 33 and place it in the position currently occupied by
11, and then try inserting 11 at the root (Figure 4.5):
1 2 3 4 5 6 7 8
22 19 17 12 10 11 33 34
Now take 22 and place it in the position currently occupied by 11, and
then try inserting 11 at the root (Figure 4.6):
196 Data Structure and Algorithm
1 2 3 4 5 6 7 8
19 12 17 11 10 22 33 34
Repeat the process taking 19 and place it in the position currently
occupied by 10, and then try inserting 10 at the root (Figure 4.7):
1 2 3 4 5 6 7 8
17 12 10 11 19 22 33 34
Repeat the process, take 17 and place it in the position currently occupied
by 11, and then try inserting 11 at the root (Figure 4.8):
1 2 3 4 5 6 7 8
12 11 10 17 19 22 33 34
Repeat the process, take 12 and place it in the position currently occupied
by 10, and then try inserting 10 at the root (Figure 4.9):
1 2 3 4 5 6 7 8
11 10 12 17 19 22 33 34
Repeat the process, take 11 and place it in the position currently occupied
by 10, and then try inserting 10 at the root (Figure 4.10):
1 2 3 4 5 6 7 8
10 11 12 17 19 22 33 34
It is clear that by repeating this strategy, we will finally arrive at a sorted
list.
A. Equivalent C Function:
void InsertFromHeap (int pos,int array[],int n)
{
198 Data Structure and Algorithm
int k,right,left,max,temp;
for(k=pos;;)
{
left=2*k+1;
right=left+1;
if(left>=n)
{
return;
}
else
if(right>=n)
{
max=left;
}
else
if(array[left]>array[right])
{
Sorting Algorithms 277
max=left;
}
else
{
max=right;
}
if(array[k]>array[max])
{
return;
}
temp=array[k];
array[k]=array[max];
array[max]=temp;
Sorting Algorithms 199
k=max;
}
}
void HeapSort(int array[],int n) // Perform heap sort
{
int i,temp;
for(i=n/2;i>=0; – –i) // Heapify-Theta(n)
{
InsertFromHeap(i,array,n);
} // Time Complexity: Theta(n)
for(i=n–1;i>0;i– –) // Time Complexity: Theta(n*lg(n));
{
temp=array[0];
array[0]=array[i];
array[i]=temp;
InsertFromHeap(0,array,i);
}
}
B. Implementation of Heap Sort Function: The following program
sort_heap.c implements the heap sort function using the array of
integers:
/* sort_heap.c */
#include <stdio.h>
#include <stdlib.h>
#define N 100
void Input(int array[],int n);
void InsertFromHeap(int pos,int array[],int n);
void HeapSort(int array[],int n); // Perform heap sort
void Print(int array[],int n);
void main()
{
int n,array[N];
200 Data Structure and Algorithm
max=right;
}
if(array[k]>array[max])
{
return;
}
temp=array[k];
array[k]=array[max];
array[max]=temp;
k=max;
}
}
void HeapSort(int array[],int n)
{
int i,temp;
for(i=n/2;i>=0; – –i)
{
InsertFromHeap(i,array,n);
}
for(i = n–1; I > 0; i– –)
{
temp=array[0];
array[0]=array[i];
array[i]=temp;
InsertFromHeap(0,array,i);
}
}
void Input(int array[],int n)
{
int i;
printf(“Please enter the number of the array:\n”);
202 Data Structure and Algorithm
for (i=0;i<n;i++)
scanf(“%d,”&array[i]);
printf(“Array before sorting: “);
for(i=0;i<n;++i)
printf(“%d,”array[i]);
printf(“\n”);
}
void Print(int array[],int n)
{
int i;
printf(“Array after sorting: “);
for(i=0;i<n;++i)
{
printf(“%d,”array[i]);
}
printf(“\n”);
}
Exercise
• Q.1. What is the purpose of writing the more complicated code to
do binary searches, when a linear one will not only find the item
if it is there, but does not even require the data to be sorted in the
first place?
• Q.2. Rewrite the bubble sort and the merge sort to produce the list
in reverse order (largest to smallest).
• Q.3. Implement a shell sort and a quick sort for the type cardinal
(as in the text) and the type real. Which factors make the
performances different for the type real? What conclusions can
you draw?
• Q.4. Write a program that will read an array of strings from a disk
file, sort it, and write it back.
• Q.5. Modify the shell sort as finally shown in the text to use a
stored array for the k-sequence. To begin with, have the program
ask you for the sequence from the keyboard. Test various
sequences and try to find an optimum one. Once you have this,
organize your work in modules as with your k-sequence safely
tucked away in the implementation part.
• Q.6. Suppose instead of using the middle item for the pivot in a
quick sort, one uses the median of the left, middle, and right items
instead. Write and test this modification, determining whether or
204 Data Structure and Algorithm
CONTENTS
5.1. Introduction..................................................................................... 206
5.2. Graph.............................................................................................. 206
5.3. Adjacent Vertices............................................................................. 207
5.4. Paths................................................................................................ 207
5.5. Cycles.............................................................................................. 208
5.6. Various Types of Graphs................................................................... 208
5.7. Trees................................................................................................ 212
5.8. Graph Representations..................................................................... 213
5.9. Minimum Path Problem................................................................... 216
5.10. Traversal Schemes of a Graph........................................................ 217
5.11. Spanning Trees............................................................................... 239
5.12. Applications of Graph.................................................................... 240
206 Data Structure and Algorithm
5.1. INTRODUCTION
This chapter covers graphs, along with their related definitions like- definition
of graph, adjacent vertices, paths, cycles, and trees etc. Various types of
graphs like- directed, undirected, connected, strongly connected, weakly
connected, unconnected, simple, and multi graphs etc., are discussed. Graph
representation includes: adjacency matrix, adjacency list and adjacency
multilists. In traversal schemes, depth first search and breadth first searches
are discussed. Shortest path problem with dijkstra algorithm is discussed.
Minimum spanning tree with their prim’s and kruskal’s algorithm are also
covered.
5.2. GRAPH
A graph G is a set of vertices(nodes) V and a set of edges(arcs) E, which
connect them. Vertices on the graph are shown as points or circles and edges
are drawn as arcs or line segments.
We write:
G = (V,E)
where; V is the finite and non empty set of vertices and the set of edges:
E = {(vi,vj)}
where; vi and vj are pair of vertices in V. Therefore, V(G), read as V of G, is
a set of vertices, and E(G), read as E of G, is a set of edges. A graph may be
pictorially represented as shown in Figure 5.1.
5.4. PATHS
A path P of length k, through a graph is a sequence of connected vertices,
each adjacent to the next. If v0 is the initial vertex and vk is the terminal
vertex, the path from v0 to vk is the sequence of vertices so that v0 is adjacent
to v1, v1 is adjacent to v2 … and vk–1 is adjacent to vk. The number of edges
on the path is called path length.
Once again, consider the graph as shown in the Figure 5.2. Some of the
paths and lengths are tabulated in Table 5.2.
208 Data Structure and Algorithm
5.5. CYCLES
A cycle is a path in which first and last vertices are the same. A graph
contains no cycles, if there is no path of non-zero length through the graph,
P = <v0,v1,…,vk> such that v0 = vk.
Let us consider the graph shown in the Figure 5.2. We may notice that
there is a path, which starts at vertex 1 and finishes at vertex 1, i.e., path
1,2,4,5,3,1. Such a path is called a cycle.
It is an unconnected graph. We may say that these are two graphs and not
one. Look at the figure in its totality and apply the definition of graph. Does
it satisfy the definition of a graph? It does. Therefore, it is one graph having
two unconnected components. Since, there are unconnected components, it
is an unconnected graph.
5. Simple and Multi Graph: A graph is said to be simple, if only
one edge is directed from any one vertex to any other vertex.
Otherwise it is called multi graph. Figure 5.8 shows such graphs.
5.7. TREES
A Tree is a special type of graph. A graph is called a tree, if it has two
properties:
• It is connected; and
• There are no cycles in the graph.
Figure 5.9 shows a graph called tree.
Vertex 1 2 3 4 5
1 0 1 1 0 1
2 1 0 1 1 0
3 1 1 0 1 1
4 0 1 1 0 0
5 1 0 1 0 0
We may observe that the adjacency matrix for an undirected graph
is symmetric, as the lower and upper triangles are the same. Also, all the
diagonal elements are zero.
Vertex 1 2 3 4 5
1 0 1 1 0 0
2 0 0 1 1 0
3 0 0 0 1 1
4 0 0 0 0 1
5 0 0 0 0 0
The total number of 1’s account for the number of edges in the digraph.
The number of 1’s in each row gives the out degree of the corresponding
vertex.
Graphs 215
The adjacent vertices may appear in the adjacency list in arbitrary order.
Also, an arrow from 2 to 3 in the list linked to 1, does not mean that 2 and
3 are adjacent.
Vertex v1 v2 v3 v4 v5 v6
v1 0 1 1 0 0 0
v2 1 0 1 1 1 0
v3 1 1 0 1 1 0
v4 0 1 1 0 1 1
v5 0 1 1 1 0 1
v6 0 0 0 1 1 0
Table 5.7 shows the process of visiting each vertex in the graph shown
in the Figure 5.15.
Let us start with v1. Its adjacent vertices are v2 and v3. Let us pick v2. Its
adjacent vertices are v1, v3, v4, and v5. v1 is already visited. Let us pick v3. Its
adjacent vertices are v1, v2, v4, and v5. v1 and v2 are 20 already visited. Let us
visit v4. Its adjacent vertices are v2, v3, v5, and v6. v2 and v3 are already visited.
Graphs 219
Let us traverse v5. Its adjacent vertices are v2, v3, v4, and v6. v2, v3 and v4 are
already visited. So, visit v6. We had v4 and v5 both are visited. Therefore, we
back track. Now, we have visited all the vertices. Therefore, the sequence
of traversal is: v1, v2, v3, v4, v5, v6. This is not a unique or the only sequence
possible for using this traversal method.
• Declaration: The following is the structure declaration for depth
first search algorithm:
#define v 10
typedef int adj_matrix[v][v];
typedef struct t_graph{
int nodes[v];
int n_nodes;
int *visited;
adj_matrix am;
}graph;
where; nodes represent the traversal order of the vertices of the graph, n_
nodes represent the total nodes in the graph, visited is the flag, which is used
to indicate whether the vertex of the graph is visited or not and am is used
to represent the adjacent matrix of the graph. The following is the algorithm
which implements the depth first search process of traversing a node within
the graph(G).
A. Algorithm: Following are the steps for depth first search:
a. [Initialize the counter with zero for storing the arrival vertices of
the graph]
Set index = 0
b. [Enter the vertices in the graph]
Read(n_nodes)
c. [Initialize all vertices in the array with FALSE to indicate the
absence of visits to the vertices]
Repeat step (d) for(i=1;i<n_nodes;i++)
d. Set visited[i] = FALSE
e. [Read adjacent matrix of the graph, enter 1 in the array for all
adjacent vertices j of vertex i and 0 for not]
220 Data Structure and Algorithm
}
}
void visit(graph *g, int k)
{
int j;
/*assign the vertex of the graph is visited */
g->visited[k] = TRUE;
g->nodes[++search_index] = k;
/* Search for visited vertex */
for(j=1;j<=g->n_nodes;j++)
{
/* Check adjacent vertex of the vertex */
if(g->am[k][j] == 1)
{
/*check the vertex of the graph is visited or not */
if (!g->visited[j])
/* Call recursively function vists */
visit(g, j);
}
}
}
C. Implementation of the Depth First Search Method: The
following program graph_dfs.c performs the traversal operation
of the graph using depth first search method. A depth first traverse
of a graph uses an additional array to flag nodes that it has visited
already:
/*graph_dfs.c*/
#include<stdio.h>
#define v 10
#define FALSE 0
#define TRUE 1
typedef int adj_matrix[v][v];
Graphs 223
}
}
for(k=1;k<=g->n_nodes;k++)
{
if (!g->visited[k])
visit(g, k);
}
printf(“!!ADJACENCY MATRIX!!\n”);
for(i=1;i<=g->n_nodes;i++)
{
for(k=1;k<=g->n_nodes;k++)
{
printf(“%d\t,”g->am[i][k]);
}
printf(“\n”);
}
i=0;
printf(“!!The sequence of traversal of a given graph in DFS is!!\n”);
while(i<g->n_nodes)
{
printf(“%d\t,”g->nodes[++i]);
}
}
void visit(graph *g, int k)
{
int j;
g->visited[k] = TRUE;
g->nodes[++search_index] = k;
for(j=1;j<=g->n_nodes;j++)
{
if(g->am[k][j] == 1)
Graphs 225
Graphs 297
{
if (!g->visited[j])
visit(g, j);
}
}
}
D. Output of the Program: This program performs the traversal of
graph using depth first search method!!
Please enter the nodes in the graph
6
Please enter data of vertex 1 for(1,1):
Please enter 1 for adjacent vertex and 0 for not
0
Please enter data of vertex 1 for(1,2):
Please enter 1 for adjacent vertex and 0 for not
1
Please enter data of vertex 1 for(1,3):
Please enter 1 for adjacent vertex and 0 for not
1
Please enter data of vertex 1 for(1,4):
Please enter 1 for adjacent vertex and 0 for not
0
Please enter data of vertex 1 for(1,5):
Please enter 1 for adjacent vertex and 0 for not
0
Please enter data of vertex 1 for(1,6):
Please enter 1 for adjacent vertex and 0 for not
0
Please enter data of vertex 2 for(2,1):
Please enter 1 for adjacent vertex and 0 for not
1
226 Data Structure and Algorithm
0
Please enter data of vertex 4 for(4,1):
Please enter 1 for adjacent vertex and 0 for not
0
Please enter data of vertex 4 for(4,2):
Please enter 1 for adjacent vertex and 0 for not
1
Please enter data of vertex 4 for(4,3):
Please enter 1 for adjacent vertex and 0 for not
1
Please enter data of vertex 4 for(4,4):
Please enter 1 for adjacent vertex and 0 for not
0
Please enter data of vertex 4 for(4,5):
Please enter 1 for adjacent vertex and 0 for not
1
Please enter data of vertex 4 for(4,6):
Please enter 1 for adjacent vertex and 0 for not
1
Please enter data of vertex 5 for(5,1):
Please enter 1 for adjacent vertex and 0 for not
0
Please enter data of vertex 5 for(5,2):
Please enter 1 for adjacent vertex and 0 for not
1
Please enter data of vertex 5 for(5,3):
Please enter 1 for adjacent vertex and 0 for not
1
Please enter data of vertex 5 for(5,4):
Please enter 1 for adjacent vertex and 0 for not
1
228 Data Structure and Algorithm
000110
!!The sequence of traversal of a given graph in DFS is!!
123456
Vertex v1 v2 v3 v4 v5
v1 0 1 1 0 1
v2 1 0 1 1 0
v3 1 1 0 1 1
v4 0 1 1 0 0
v5 1 0 1 0 0
We start with vertex say, v1. Its adjacent vertices are v2, v3, and v5. We
visit all one by one. The list of visited vertices is v1, v3, v4, and v5. Now, we
pick one of these, say v2. Its adjacent vertices are v1, v3, and v4. The unvisited
230 Data Structure and Algorithm
for(i=1;i<=g->n_nodes;i++)
{
for(j=1;j<=g->n_nodes;j++)
{
scanf(“%d,”&g->am[i][j]);
}
}
/*check the vertex of the graph is visited or not */
for(k=1;k<=g->n_nodes;k++)
{
if (!g->visited[k])
{
/* Insert visited vertex in the queue */
insert_queue(q,k);
do
{
/* Delete vertex from the queue */
k = delete_queue(q);
/*assign the vertex of the graph is visited*/
g->visited[k] = TRUE;
for(j=1;j<=g->n_nodes;j++)
{
/* Check adjacent vertex of the vertex */
if(g->am[k][j] == 0)
continue;
/*check the vertex of the graph is visited or not */
if (!g->visited[j])
{
/*assign the vertex of the graph is visited */
g->visited[j] = TRUE;
/* Insert visited vertex in the queue */
Graphs 233
insert_queue(q, j);
}
}
}while(front!=rear);
}
}
/* Print the adjacency matrix of the graph !!*/
for(i=1;i<=g->n_nodes;i++)
{
for(k=1;k<=g->n_nodes;k++)
{
printf(“%d\t,”g->am[i][k]);
}
printf(“\n”);
}
/*The sequence of traversal of a given graph in BFS is*/
i=0;
while(i<g->n_nodes)
{
printf(“%d\t,”q[++i]);
}
}
C. Implementation of the Breath First Search Method: The
following program graph_bfs.c performs the traversal operation
of the graph using breath first search method. A breath first
traverse of a graph uses an additional array to flag nodes that it
has visited already:
/*graph_bfs.c*/
#include<stdio.h>
#define v 10
#define FALSE 0
#define TRUE 1
234 Data Structure and Algorithm
printf(“%d\t,”g->am[i][k]);
}
printf(“\n”);
}
i=0;
printf(“!!The sequence of traversal of a given graph in BFS is!!\n”);
while(i<g->n_nodes)
{
printf(“%d\t,”q[++i]);
}
}
void insert_queue(int q[], int k)
{
q[rear] = k;
rear++;
}
int delete_queue(int q[])
{
int item;
item = q[front];
front++;
if(front==v)
{
front=1;
rear=1;
}
return(item);
}
D. Output of the Program: This program performs the traversal of
graph using breath first search method!!
Please enter the nodes in the graph
5
Graphs 237
vertex v as an initial partial tree and add edges one by one so that each edge
joins a new vertex to the partial tree. In general, if there are n vertices in the
graph we shall construct a spanning tree in (n – 1) steps, i.e., (n – 1) edges
are needed to be added. For example, the following graph has four distinct
spanning trees (Figures 5.17 and 5.18):
adjacency matrix and path represent the path of the minimum spanning tree.
The following is the algorithm, which implements the prim’s algorithm of
tree (T):
A. Algorithm: Following are the steps for prim’s algorithm.
a. [Read the vertices in the graph]
Read(n_nodes)
b. [Read adjacent matrix of the graph. The weight will be taken
infinity, if there is no direct path between one vertex to another
vertex, we have used 1500 for infinity, enter cost 0 for vertex to
itself]
Repeat step (c) for(i=0;i<n_nodes;v++),
for(j=0;j<n_nodes;j++)
c. Read adj_matrix[i][j]
d. [Write the adjacent matrix of the graph]
Repeat for(i=0;i<n_nodes;i++)
Repeat for(j=0;j<n_nodes;j++)
Print(adj_matrix[i][j])
e. [Initially none of the vertices are selected]
for(i=0;i<n_nodes;i++)
Set selected[i] = FALSE
f. [Initially enters 0 in the minimum spanning tree matrix]
for(i=0;i<n_nodes;i++)
for(j=0;j<n_nodes;j++)
Set tree[i][j]=0
g. [Select the vertex 0 as the starting vertex]
Set selected[0]=TRUE,
path[0]=0,
length = 1
h. [Find the nearest neighbor vertex of one of selected vertices]
Repeat step (i) to (n) while(length<=n_nodes)
i. Set min = INFINITY
j. Repeat step(k) to (m)for(i=0;i<n_nodes;i++)
244 Data Structure and Algorithm
k. If(selected[i]==TRUE) then
l. Repeat step(m) for(j=0;j<n_nodes;j++)
m. If(selected[j]==FALSE) then
If(adj_matrix[i][j] <min) then
Set min = adj_matrix[i][j],
u = i,
w = j,
n. [Include the nearest neighbor into the tree]
Set tree[u][w] = 1,
selected[w] = TRUE,
path[++k] = w,
length = length + 1
o. [Write the minimum spanning tree adjacency matrix]
Repeat for(i=0;i<n_nodes;i++)
Repeat for(j=0;j<n_nodes;j++)
Print(tree[i][j])
p. [Write the shortest path from the source to all vertices]
Repeat for(i=0;i<k;i++)
Print(path[i])
q. End.
B. Equivalent Function in C
void prim(tree *t)
{
int i,j,k=0,w,u,p,min;
/* Read the cost matrix */
for(i=0;i<t->n_nodes;i++)
{
for(j=0;j<t->n_nodes;j++)
{
scanf(“%d,”&t->adj_matrix[i][j]);
}
}
Graphs 245
{
if(t->selected[i]==TRUE)
{
for(j=0;j<t->n_nodes;j++)
{
if(t->selected[j]==FALSE)
{
if(t->adj_matrix[i][j] <min)
{
min = t->adj_matrix[i][j];
u = i;
w = j;
}
}
}
}
}
/* Include the nearest neighbor into the tree */
t->tree[u][w] = 1;
t->selected[w] = TRUE;
t->path[++k] = w;
length++;
} /* End of While loop */
/* the minimum spanning tree adjacency matrix is*/
for(i=0;i<t->n_nodes;i++)
{
for(j=0;j<t->n_nodes;j++)
{
printf(“%5d\t,”t->tree[i][j]);
}
}
Graphs 247
Source Graph
Adjacency Matrix
Initial Tree
Final Stage
void main()
{
tree t;
printf(“This program finds the minimum spanning tree of a undirected graph
using prim’s algorithm!!\n”);
printf(“Please enter how many edges in the graph:\n”);
scanf(“%d,”&t.n_nodes);
prim(&t);
}
void prim(tree *t)
{
int i,j,k=0,w,u,min,length;
for(i=0;i<t->n_nodes;i++)
{
for(j=0;j<t->n_nodes;j++)
{
printf(“Please enter weight for visiting edge %d to edge %d:,”i,j);
scanf(“%d,”&t->adj_matrix[i][j]);
}
}
printf(“THE ADJACENT MATRIX OF THE GRAPH IS\n”);
for(i=0;i<t->n_nodes;i++)
{
for(j=0;j<t->n_nodes;j++)
{
printf(“%5d\t,”t->adj_matrix[i][j]);
}
printf(“\n”);
}
for(i=0;i<t->n_nodes;i++)
{
Graphs 251
t->selected[i] = FALSE;
}
for(i=0;i<t->n_nodes;i++)
for(j=0;j<t->n_nodes;j++)
{
t->tree[i][j]=0;
}
}
t->selected[0]=TRUE;
t->path[0]=0;
length = 1;
while(length<=t->n_nodes)
{
min = INFINITY;
for(i=0;i<t->n_nodes;i++)
{
if(t->selected[i]==TRUE)
{
for(j=0;j<t->n_nodes;j++)
{
if(t->selected[j]==FALSE)
{
if(t->adj_matrix[i][j] <min)
{
min = t->adj_matrix[i][j];
u = i;
w = j;
}
}
}
}
252 Data Structure and Algorithm
}
t->tree[u][w] = 1;
t->selected[w] = TRUE;
t->path[++k] = w;
length++;
}
printf(“THE MINIMUM SPANNING TREE ADJANCENCY MATRIX
IS\n”);
for(i=0;i<t->n_nodes;i++)
{
for(j=0;j<t->n_nodes;j++)
{
printf(“%5d\t,”t->tree[i][j]);
}
printf(“\n”);
}
/* print the shortest path from the source to all vertices */
printf(“The minimum spanning tree path using prim’s algorithm is\n”);
for(i=0;i<k;i++)
printf(“%d\t,”t->path[i]);
printf(“\n”);
}
B. Output of the Program: This program finds the minimum
spanning tree of a undirected graph using prim’s algorithm!!
Please enter how many edges in the graph:
5
Please enter weight for visiting edge 0 to edge 0: 0
Please enter weight for visiting edge 0 to edge 1: 5
Please enter weight for visiting edge 0 to edge 2: 3
Please enter weight for visiting edge 0 to edge 3: 1500
Please enter weight for visiting edge 0 to edge 4: 2
Please enter weight for visiting edge 1 to edge 0: 5
Graphs 253
Set visited[0]=TRUE,
D[0]=0,
path[0] = 0
e. [Set remaining vertices are unvisited and assigns the cost of
remaining vertices from source vertex, into the array of best
estimate D]
for(u=1;u<n_nodes;u++)
Set visited[u] = FALSE,
D[u] = cost[0][u]
f. Repeat step (g) to (j) for(i=1;i<n_nodes;i++)
Set min = INFINITY
g. [Find the closest vertex u to vertex 0]
for(w=1;w<n_nodes;w++)
if(!visited[w])
if(D[w] <min)
Set u = w,
min = D[w]
h. [Add vertex u to the set of visited vertices]
Set visited[u] = TRUE;
i. [Update the remaining costs in D]
for(w=1;w<n_nodes;w++)
if(!visited[w])
if((min + cost[u][w])< D[w])
D[w] = min + cost[u][w]
path[k] = u
j. [Write the shortest path from the source to all other vertices]
for(p=0;p<=k;++p)
write path[p]
k++
k. End.
B. Equivalent Function in C
void dijkstra(graph *g)
Graphs 259
{
int i,j,k=0,w,u,p,min;
/* Read the cost matrix */
for(i=0;i<g->n_nodes;i++)
{
for(j=0;j<g->n_nodes;j++)
{
scanf(“%d,”&g->cost[i][j]);
}
}
/*THE ADJACENT COST MATRIX IS: */
for(i=0;i<g->n_nodes;i++)
{
for(j=0;j<g->n_nodes;j++)
{
printf(“%5d\t,”g->cost[i][j]);
}
printf(“\n”);
}
/* Assign the source vertex 0 in the set of visited vertices */
g->visited[0]=TRUE;
g->D[0]=0;
g->path[0] = 0;
printf(“%d\n,”g->path[0]);
k++;
for(u=1;u<g->n_nodes;u++)
{
g->visited[u] = FALSE;
g->D[u] = g->cost[0][u];
}
/* Start the main loop, add one vertex u to S on each pass */
260 Data Structure and Algorithm
for(i=1;i<g->n_nodes;i++)
{
min = INFINITY;
/* Find the closest vertices u to vertex 0 */
for(w=1;w<g->n_nodes;w++)
{
if(!g->visited[w])
if(g->D[w] <min)
{
u = w;
min = g->D[w];
}
}
/* Add u to the set S */
g->visited[u] = TRUE;
/* Update the remaining distances in D */
for(w=1;w<g->n_nodes;w++)
if(!g->visited[w])
if(min + g->cost[u][w]<g->D[w])
g->D[w] = min + g->cost[u][w];
g->path[k] = u;
/* print the shortest path from the source to other vertices */
for(p=0;p<=k;++p)
printf(“%d\t,”g->path[p]);
k++;
printf(“\n”);
}
}
Graphs 261
Source
{
int i,j,k=0,w,u,p,min;
for(i=0;i<g->n_nodes;i++)
{
for(j=0;j<g->n_nodes;j++)
{
printf(“Please enter cost for visiting vertex %d to vertex %d:,”i,j);
scanf(“%d,”&g->cost[i][j]);
}
}
printf(“THE ADJACENT COST MATRIX IS: \n”);
for(i=0;i<g->n_nodes;i++)
{
for(j=0;j<g->n_nodes;j++)
{
printf(“%5d\t,”g->cost[i][j]);
}
printf(“\n”);
}
printf(“The shortest path of the graph is:\n”);
g->visited[0]=TRUE;
g->D[0]=0;
g->path[0] = 0;
printf(“%d\n,”g->path[0]);
k++;
for(u=1;u<g->n_nodes;u++)
{
g->visited[u] = FALSE;
g->D[u] = g->cost[0][u];
}
for(i=1;i<g->n_nodes;i++)
Graphs 265
{
min = INFINITY;
for(w=1;w<g->n_nodes;w++)
{
if(!g->visited[w])
if(g->D[w] <min)
{
u = w;
min = g->D[w];
}
}
g->visited[u] = TRUE;
for(w=1;w<g->n_nodes;w++)
if(!g->visited[w])
if(min + g->cost[u][w]<g->D[w])
g->D[w] = min + g->cost[u][w];
g->path[k] = u;
for(p=0;p<=k;++p)
printf(“%d\t,”g->path[p]);
k++;
printf(“\n”);
}
}
B. Output of the Program: This program finds the shortest path of
a directed graph using Dijkstra’s algorithm!!
Please enter how many vertices in the graph:
5
Please enter cost for visiting vertex 0 to vertex 0: 0
Please enter cost for visiting vertex 0 to vertex 1: 5
Please enter cost for visiting vertex 0 to vertex 2: 3
Please enter cost for visiting vertex 0 to vertex 3: 1500
Please enter cost for visiting vertex 0 to vertex 4: 2
266 Data Structure and Algorithm
Exercise
• Q.1. Write a C program for kruskal’s minimum spanning tree
algorithm.
• Q.2. Give an example of a connected graph such that removal of
any edge results in a graph that is not connected.
• Q.3. Consider the graph given in the figure below:
Is it possible to trace the above graph, beginning, and ending at the same
point, without lifting your pencil from the paper and without retracing lines?
Justify your answer.
268 Data Structure and Algorithm
Find the length of the shortest path and the shortest path between:
i. A and F;
ii. A and Z;
iii. D and H.
• Q.6. Write a program that accepts adjacency matrix as an input
and outputs a list of edges given as pairs of positive integers.
• Q.7. Draw minimum cost spanning tree for the graph given below
and also find its cost.
• Q.8. Find the shortest paths from source vertex to all the vertices
for the graph given in the above figure using dijkstra’s algorithm.
• Q.9. Show the visiting of all the nodes of the given graph using
DFS and BFS traversal schemes.
CHAPTER 6
ALGORITHM AND ITS ANALYSIS
CONTENTS
6.1. Analysis of Algorithm....................................................................... 270
270 Data Structure and Algorithm
CONTENTS
7.1. Algorithm for Insertion in One Dimensional Array........................... 274
7.2. Algorithm for Deletion in One Dimensional Array........................... 274
274 Data Structure and Algorithm
cin>>pos1;
for(i=pos;i<=n;i++)
a[i]=a[i+1];
cout<<“\n element in array after deletion of no”;
for(i=1;i<n;i++)
cout<<a[i]<<“ “;
getch();
}
Ø Output:
• Viva Questions:
• What are the advantages of one dimensional array?
• What are the disadvantages of one dimensional array?
• What is static time compilation?
EXPT. No. 2. Write a Program to Implement Matrix Addition and
Subtraction.
• Aim: To implement a program of matrix addition and subtraction
• Theory: Algorithm for matrix addition and subtraction
• Matrices Addition: The addition of two matrices A m*n and Bm*n
gives a matrix Cm*n. The elements of C are sum of corresponding
elements in A and B which can be shown as:
Data Structure Laboratory 277
}
}
for(i=1;i<=2;i++)
{
for(j=1;j<=2;j++)
{
cout<< c[i][j]<<“ “;
}
cout<<“\n”;
}
cout<<“\n matrix subraction is”;
for(i=1;i<=2;i++)
{
for(j=1;j<=2;j++)
{
d[i][j]=a[i][j]-b[i][j];
}
}
for(i=1;i<=2;i++)
{
for(j=1;j<=2;j++)
{
cout<< d[i][j]<<“ “;
}
cout<<“\n”;
}
getch();
}
• Output:
280 Data Structure and Algorithm
• Viva Questions:
• What is the running time complexity of Matrix Addition?
• What is the running time complexity of Matrix Subtraction?
EXPT. No. 3 Write a Program to Implement Matrix Multiplication.
• Aim: To implement a program of matrix multiplication.
• Theory: Matrix multiplication falls into two general categories:
Matrix C and D below cannot be multiplied together because the number
of columns in C does not equal the number of rows in D. In this case, the
multiplication of these two matrices is not defined
• Algorithm for Matrix Multiplication:
Matmul(a,b,m,n,p)
for(i=1 to m)
for(j = 1 to)
c[i][j] =0; for(k = 1 to n)
c[i][j] =c[i][j]+a[i][k]*b[k][j]
exit
Ø Program:
#include<stdio.h>
#include<conio.h>
void main( )
{
int a[2][2], b[2][2],s[2][2];
int i,j,k;
clrscr();
Data Structure Laboratory 281
}
getch();
Ø Output:
• Viva Questions:
1. Consider the two matrices P and Q which are 10 x 20 and 20 x
30 matrices respectively. What is the number of multiplications
required to multiply the two matrices?
2. Consider the brute force implementation in which we find all the
possible ways of multiplying the given set of n matrices. What is
the time complexity of this implementation?
3. Which of the following is the recurrence relation for the matrix
chain multiplication problem where mat[i–1] * mat[i] gives the
dimension of the ith matrix?
4. What is the time complexity of the above dynamic programming
implementation of the matrix chain problem?
5. Which of the following methods can be used to solve the matrix
chain multiplication problem?
EXPT. No. 4. Write a Program to Implement Stack Using Array.
• Aim: To implement a program of stack using array.
• Theory: A stack is a container of objects that are inserted and
removed according to the last-in first-out (LIFO) principle. In
the pushdown stacks only two operations are allowed: push the
item into the stack, and pop the item out of the stack. A stack
is a limited access data structure – elements can be added and
removed from the stack only at the top. Push adds an item to the
top of the stack, pop removes the item from the top. A helpful
Data Structure Laboratory 283
{
cout<<“\n1.push”;
cout<<“\n2.pop”;
cout<<“\n3.Display”;
cout<<“\n4.Quit”;
cout<<“\nEnter your choice: “;
cin>>ch;
switch(ch)
{
case 1: push();break;
case 2: pop();break;
case 3:display();break;
case 4:return;
default:cout<<“Wrong choice”;
}
}
while(ch!=4);
getch();
}
void push()
{
if(top==MAXSIZE–1)
cout<<“stack is full”;
else
{
int no;
cout<<“enter the no”;
cin>>no;
top=top+1;
Data Structure Laboratory 285
a[top]=no;
}
}
void pop()
{
int no;
if(top== –1)
cout<<“stack is empty”;
else
{
no=a[top];
cout<<“deleted element is”<<no;
top=top–1;
}
}
void display()
{
if(top==–1)
cout<<“stack is empty”;
else
{
cout<<“status of stack is”;
for(int i=0;i<=top;i++)
cout<<“\n”<<a[i];
}
}
286 Data Structure and Algorithm
• Output:
• Viva Questions:
1. What is a stack?
2. What are the applications of stack?
3. Explain push algorithm of stack?
4. Explain pop algorithm of stack?
5. Explain algorithm of 2 stack in a single array?
EXPT. No. 5. Write a Program to Implement Queue Using Array.
• Aim: To implement a program of queue using array.
• Theory: A queue is an ordered collection of items where the
addition of new items happens at one end, called the “rear,” and
the removal of existing items occurs at the other end, commonly
called the “front.” As an element enters the queue it starts at the
rear and makes its way toward the front, waiting until that time
when it is the next element to be removed.
The most recently added item in the queue must wait at the end of the
collection. The item that has been in the collection the longest is at the front.
This ordering principle is sometimes called FIFO, first-in first-out. It is also
known as “first-come first-served.
• Algorithm for Insertion in Queue:
procedure enqueue(data)
if queue is full
Data Structure Laboratory 287
return overflow
endif
rear ← rear + 1
queue[rear] ← data
return true
end procedure
• Algorithm for Deletion in Queue:
procedure dequeue
if queue is
return underflow
end if
data = queue[front]
front ← front + 1
return true
end procedure
• Program:
#include<iostream.h>
#include<conio.h>
#define MAXSIZE 100
void insert();
void del();
void display();
int front =–1;
int rear=–1;
int a[MAXSIZE];
void main()
{
int ch;
clrscr();
do
{
288 Data Structure and Algorithm
cout<<“\n1.Insert”;
cout<<“\n2.Delete”;
cout<<“\n3.Display”;
cout<<“\n4.Quit”;
cout<<“\nEnter your choice: “;
cin>>ch;
switch(ch)
{
case 1: insert();break;
case 2: del();break;
case 3:display();
break;
case 4:return;
default:cout<<“Wrong choice”;
}
}
while(ch!=4);
getch();
}
void insert()
{
if(rear>=MAXSIZE)
cout<<“queue is full”;
else
{
int no;
cout<<“enter the no”;
cin>>no;
if(front==–1)
front=rear=0;
else
Data Structure Laboratory 289
rear=rear+1;
a[rear]=no;
}
}
void del()
{
int no;
if(front==–1)
cout<<“queue is empty”;
else
{
no=a[front];
cout<<“deleted element is”<<no;
if(front==rear)
front=rear=–1;
else
front=front+1;
}
}
void display()
{
if(front==–1)
cout<<“queue is empty”;
else
{
cout<<“status of queue is”;
for(int i=front;i<=rear;i++)
cout<<“\n”<<a[i];
}
}
290 Data Structure and Algorithm
• Output:
• Viva Questions:
1. What is queue?
2. What is circular queue?
3. What are the applications of queue?
4. Explain insertion algorithm of queue?
5. Explain deletion algorithm of queue?
6. What is overflow and underflow condition for queue?
EXPT. No. 6. Write a Program to Implement Singly Linked List.
• Aim: To implement a program of singly linked list.
• Theory: Linked list is a collection of Nodes. Each node having two
parts. First part represents value of the node and second part repre-
sents an address of the next node. If Next node is not present then it
contains NULL value.
• Algorithm of Insertion:
In a single linked list, the insertion operation can be performed in three
ways. They are as follows:
Inserting At Beginning of the list
Inserting At End of the list
Inserting At Specific location in the list
• Inserting at Beginning of the List:
We can use the following steps to insert a new node at beginning of the
single linked list
• Step 1: Create a newNode with given value.
• Step 2: Check whether list is Empty (head == NULL)
• Step 3: If it is Empty then, set newNode→next = NULL and head
= newNode.
• Step 4: If it is Not Empty then, set newNode→next = head and
head = newNode.
• Inserting at End of the List: We can use the following steps to
insert a new node at end of the single linked list:
• Step 1: Create a newNode with given value and newNode →
next as NULL.
• Step 2: Check whether list is Empty (head == NULL).
• Step 3: If it is Empty then, set head = newNode.
• Step 4: If it is Not Empty then, define a node pointer temp and
initialize with head.
• Step 5: Keep moving the temp to its next node until it reaches
to the last node in the list (until temp → next is equal to NULL).
• Step 6: Set temp → next = newNode.
• Inserting At Specific Location in the List (After a Node): We
can use the following steps to insert a new node after a node in
the single linked list:
• Step 1: Create a newNode with given value.
• Step 2: Check whether list is Empty (head == NULL)
• Step 3: If it is Empty then, set newNode → next = NULL and
head = newNode.
292 Data Structure and Algorithm
• Step 12: If temp1 is not first node and not last node then set
temp2 → next = temp1 → next and delete
temp1 (free(temp1)).
• Program:
#include<iostream.h>
#include<conio.h>
#include<malloc.h>
void insert1();void insert2();void insert3();
void del1();void del2();void del3();
void display();
struct node
{int data;
struct node *add;
} *start=NULL;
void main()
{
int ch;
clrscr();
do
{
cout<<“\n1.Insert at Beginning “;
cout<<“\n2.Insert at End “;
cout<<“\n3.Insert at Specified Position”;
cout<<“\n4.Delete at Beginning “;
cout<<“\n5.Delete at End “;
cout<<“\n6.Delete at Specified Position”;
cout<<“\n7.Display”;
cout<<“\n8.Quit”;
cout<<“\nEnter your choice: “;
cin>>ch;
switch(ch)
{
Data Structure Laboratory 295
case 1: insert1();break;
case 2: insert2();break;
case 3: insert3();break;
case 4: del1();break;
case 5: del2();break;
case 6: del3();break;
case 7:display();break;
case 8:return;
default:cout<<“Wrong choice”;
}
}while(ch!=8);
getch();
}
void insert1()
{
struct node *ptr;
int no;
ptr = (struct node *)malloc(sizeof(struct node));
cout<<“enter the no: “;
cin>>no;
ptr->data=no;
if(start==NULL)
ptr->add=NULL;
else
ptr->add=start;
start=ptr;
}
void insert2()
{
struct node *ptr,*temp; int no;
ptr = (struct node *)malloc(sizeof(struct node));
296 Data Structure and Algorithm
}
}
ptr = (struct node *)malloc(sizeof(struct node));
cout<<“enter the no: “;
cin>>no;
ptr->data=no;
ptr->add=temp;
temp1->add=ptr;
}
void del1()
{
struct node *tmp;
if(start==NULL)
cout<<“linked list empty”;
else
{
tmp=start;
start=start->add;
cout<<“deleted element is”<<tmp->data;
free(tmp);
}
}
void del2()
{
struct node *tmp,*ptr;
if(start==NULL)
cout<<“linked list empty”;
else if(start->add==NULL)
{
tmp=start;
start=NULL;
298 Data Structure and Algorithm
}
cout<<“deleted element is”<<ptr->data;
temp->add=ptr->add;
free(ptr);
}
}
void display()
{
struct node *ptr;
ptr=start;
while(ptr->add!=NULL)
{
cout<<“\n”<<ptr->data;
ptr=ptr->add;
}
cout<<“\n”<<ptr->data;
}
• Output:
• Viva Questions:
1. What is singly linked list?
2. What are the advantages of singly linked list?
3. What are the applications of singly linked list?
4. What is the condition for linked list overflow and underflow?
5. How linked list is represented in memory?
EXPT. No. 7. Write a Program to Implement Bubble Sort.
• Aim: To implement a program of bubble sort.
• Theory: The algorithm gets its name from the way smaller elements
300 Data Structure and Algorithm
#include<conio.h>
void main()
{
int a[20],i,n,temp;
clrscr();
cout<<“enter the no of element in array\n”;
cin>>n;
cout<<“enter the element in array”;
for(i=0;i<n;i++)
{
cin>>a[i];
}
for(i=0;i<n;i++)
{
for(int j=0;j<n–1–i; j + +)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
cout<<“element after sorting are”;
for(i=0;i<n;i++)
{
cout<<“\n”<<a[i];
}
getch();
}
302 Data Structure and Algorithm
• Output:
• Viva Questions:
1. What is the running time of bubble sort is best case
2. What is the running time of bubble sort in worst case?
3. What is the running time of bubble sort in average case?
EXPT. No. 8. Write a Program to Implement Insertion Sort.
• Aim: To implement a program of insertion sort.
• Theory: Insertion sort is an example of an incremental
algorithm; it builds the sorted sequence one number at a time.
This is perhaps the simplest example of the incremental insertion
technique, where we build up a complicated structure on n items
by first building it on n – 1 items and then making the necessary
changes to fix things in adding the last item. The given sequences
are typically stored in arrays. We also refer the numbers as keys.
Along with each key may be additional information, known as
satellite data. [Note that “satellite data” does not necessarily
come from satellite!]. Since multiple keys with the same value
are placed in the sorted array in the same order that they appear
in the input array, Insertion sort is stable. This algorithm does not
require extra memory.
– For Insertion sort we say the worst-case running time is
θ(n2), and the best-case running time is θ(n).
– Insertion sort use no extra memory it sort in place.
– The time of Insertion sort is depends on the original order of
an input. It takes a time in Ω(n2) in the worst-case, despite
the fact that a time in order of n is sufficient to solve large
instances in which the items are already sorted.
– Algorithm of Insertion Sort:
INSERTION_SORT (A)
Data Structure Laboratory 303
FOR j ← 2 TO length[A]
DO key ← A[j]
{Put A[j] into the sorted sequence A[1. j – 1]}
i←j–1
WHILE i > 0 and A[i] > key
DO A[i +1] ← A[i]
i←i–1
A[i + 1] ← key
Program:
#include<iostream.h>
#include<conio.h>
void main()
{
int a[20],i,n,temp,j;
clrscr();
cout<<“enter the no of element in array\n”;
cin>>n;
cout<<“enter the element in array”;
for(i=0;i<n;i++)
{
cin>>a[i];
}
for(i=0;i<n;i++)
{
temp=a[i];
j = i – 1;
while((j>=0)&&(a[j]>temp))
{
a[j+1]=a[j];
j = j – 1;
}
304 Data Structure and Algorithm
a[j+1]=temp;
}
cout<<“element after sorting are”;
for(i=0;i<n;i++)
{
cout<<“\n”<<a[i];
}
getch();
}
• Output:
• Viva Questions:
1. What is the running time of insertion sort is best case?
2. What is the running time of Insertion sort in worst case?
3. What is the running time of Insertion sort in average case?
EXPT. No. 9. Write a Program to Implement Selection Sort.
• Aim: To implement a program of selection sort.
• Theory: Selection sort is not difficult to analyze compared to other
sorting algorithms since none of the loops depend on the data in
the array. Selecting the lowest element requires scanning all n ele-
ments (this takes n – 1 comparisons) and then swapping it into the
first position. Finding the next lowest element requires scanning the
remaining n – 1 elements and so on, for (n – 1) + (n – 2) +… + 2 +
1 = n(n – 1) / 2 ∈ Θ(n2) comparisons (see arithmetic progression).
Each of these scans requires one swap for n – 1 elements (the final
element is already in place).
• Algorithm of Selection Sort:
void selectionsort(int a[],int n)
BEGIN
Data Structure Laboratory 305
int i,j,large,ind;
for(i=n–1;i>0;i– –)
DO
large = a[0];
ind = 0;
for(j=1; j<=i; j++)
DO
if(a[j]>large)
BEGIN
large = a[j];
ind = j;
END IF
END-FOR
a[ind] = a[i];
a[i] = large;
END-FOR
End
• Program:
#include<iostream.h>
#include<conio.h>
void main()
{
int a[20],i,n,temp,loc,min;
clrscr();
cout<<“enter the no of element in array\n”;
cin>>n;
cout<<“enter the element in array”;
for(i=0;i<n;i++)
{
cin>>a[i];
}
for(i=0;i<n;i++)
{
min=a[i];
loc=i;
306 Data Structure and Algorithm
for(int j=i+1;j<n;j++)
{
if(a[j]<min)
{
min=a[j];
loc=j;
}
}
if(loc!=i)
{
temp=a[i];
a[i]=a[loc];
a[loc]=temp;
}
}
cout<<“element after sorting are”;
for(i=0;i<n;i++)
{
cout<<“\n”<<a[i];
}
getch();
}
• Output:
• Viva Questions:
1. What is the running time of selection sort is best case?
2. What is the running time of selection sort in worst case?
Data Structure Laboratory 307
{
if(a[i]==no)
{
flag=1;
pos=i;
break;
}
}
if(flag==1)
cout<<“\n search sucessful no found at position”<<pos;
else
cout<<“\n search unsucessful”;
getch();
}
• Output:
• Viva Questions:
1. What is the running time of linear search algorithm?
2. What are the advantages of linear search?
3. What are the disadvantages of linear search?
EXPT. No. 11. Write a Program to Implement Binary Search.
• Aim: To implement a program of binary search.
• Theory: Techniques for searching an ordered list in which we
first check the middle item and – based on that comparison –
Data Structure Laboratory 309
“discard” half the data. The same procedure is then applied to the
remaining half until a match is found or there are no more items
left.
A binary search halves the number of items to check with each iteration,
so locating an item (or determining its absence) takes logarithmic time. A
binary search is a dichotomic divide and conquer search algorithm.
• Algorithm of Binary Search:
int binary_search(int A[], int key, int imin, int imax)
{
// test if array is empty
if (imax < imin)
// set is empty, so return value showing not found
return KEY_NOT_FOUND;
else
{
// calculate midpoint to cut set in half
int imid = midpoint(imin, imax);
// three-way comparison
if (A[imid] > key)
// key is in lower subset
return binary_search(A, key, imin, imid–1);
else if (A[imid] < key)
// key is in upper subset
return binary_search(A, key, imid+1, imax);
else
// key has been found
return imid;
}
}
• Program:
#include<iostream.h>
#include<conio.h>
310 Data Structure and Algorithm
void main()
{
int a[20],i,n,temp,no,loc,beg,end,mid,flag;
clrscr();
cout<<“enter the no of element in array\n”;
cin>>n;
cout<<“enter the element in array”;
for(i=0;i<n;i++)
{
cin>>a[i];
}
for(i=0;i<n;i++)
{
for(int j = 0; j < n – 1 – i; j+ +)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
cout<<“enter the element to be searched”;
cin>>no;
loc=0;
beg=0;
end=n – 1;
while((beg<=end)&&(no!=a[mid]))
{
mid=((beg+end)/2);
Data Structure Laboratory 311
if(no==a[mid])
{
cout<<“\nsearch is successful”;
loc=mid;
cout<<“\nposition of number”<<loc;
flag=flag+1;
}
if(no<a[mid])
end=mid–1;
else
beg=mid+1;
}
if(flag==0)
cout<<“search is not sucessful”;
getch();
}
• Output:
• Viva Questions:
• What is the running time of binary search algorithm?
• What is divide and conquer approach?
CHAPTER 8
VIVA QUESTIONS