Mohanty S. Data Structure and Algorithms Using C++. A Practical Implementation 2021
Mohanty S. Data Structure and Algorithms Using C++. A Practical Implementation 2021
Cover
Title Page
Copyright
Preface
1 Introduction to Data Structure
1.1 Definition and Use of Data Structure
1.2 Types of Data Structure
1.3 Algorithm
1.4 Complexity of an Algorithm
1.5 Efficiency of an Algorithm
1.6 Asymptotic Notations
1.7 How to Determine Complexities
1.8 Questions
2 Review of Concepts of ‘C++’
2.1 Array
2.2 Function
2.3 Pointer
2.4 Structure
2.5 Questions
3 Sparse Matrix
3.1 What is Sparse Matrix
3.2 Sparse Matrix Representations
3.3 Algorithm to Represent the Sparse Matrix
3.4 Programs Related to Sparse Matrix
3.5 Why to Use Sparse Matrix Instead of Simple Matrix?
3.6 Drawbacks of Sparse Matrix
3.7 Sparse Matrix and Machine Learning
3.8 Questions
4 Concepts of Class
4.1 Introduction to CLASS
4.2 Access Specifiers in C++
4.3 Declaration of Class
4.4 Some Manipulator Used In C++
4.5 Defining the Member Functions Outside of the Class
4.6 Array of Objects
4.7 Pointer to Object
4.8 Inline Member Function
4.9 Friend Function
4.10 Static Data Member and Member Functions
4.11 Constructor and Destructor
4.12 Dynamic Memory Allocation
4.13 This Pointer
4.14 Class Within Class
4.15 Questions
5 Stack
5.1 STACK
5.2 Operations Performed With STACK
5.3 ALGORITHMS
5.4 Applications of STACK
5.5 Programming Implementations of STACK
5.6 Questions
6 Queue
6.1 Queue
6.2 Types of Queue
6.3 Linear Queue
6.4 Circular Queue
6.5 Double Ended Queue
6.6 Priority Queue
6.7 Programs
6.8 Questions
7 Linked List
7.1 Why Use Linked List?
7.2 Types of Link List
7.3 Single Link List
7.4 Programs Related to Single Linked List
7.5 Double Link List
7.6 Programs on Double Linked List
7.7 Header Linked List
7.8 Circular Linked List
7.9 Application of Linked List
7.10 Garbage Collection and Compaction
7.11 Questions
8 TREE
8.1 Tree Terminologies
8.2 Binary Tree
8.3 Representation of Binary Tree
8.4 Operations Performed With the Binary Tree
8.5 Traversing With Tree
8.6 Conversion of a Tree From Inorder and Preorder
8.7 Types of Binary Tree
8.8 Expression Tree
8.9 Binary Search Tree
8.10 Height Balanced Tree (AVL Tree)
8.11 Threaded Binary Tree
8.12 Heap Tree
8.13 Huffman Tree
8.14 Decision Tree
8.15 B-Tree
8.16 B + Tree
8.17 General Tree
8.18 Red–Black Tree
8.19 Questions
9 Graph
9.1 Graph Terminologies
9.2 Representation of Graph
9.3 Traversal of Graph
9.4 Spanning Tree
9.5 Single Source Shortest Path
9.6 All Pair Shortest Path
9.7 Topological Sorting
9.8 Questions
10 Searching and Sorting
10.1 Linear Search
10.2 Binary Search
10.3 Bubble Sort
10.4 Selection Sort
10.5 Insertion Sort
10.6 Merge Sort
10.7 Quick Sort
10.8 Radix Sort
10.9 Heap Sort
10.10 Questions
11 Hashing
11.1 Hash Functions
11.2 Collisions
11.3 Collision Resolution Methods
11.4 Clustering
11.5 Questions
Index
End User License Agreement
Scrivener Publishing
100 Cummings Center, Suite 541J
Beverly, MA 01915-6106
Publishers at Scrivener
Martin Scrivener ([email protected])
Phillip Carmical ([email protected])
Data Structure and Algorithms
Using C++
A Practical Implementation
Edited by
Organization of data
Accessing methods
Degree of associativity
Processing alternatives for information
The data structures are the building blocks of a program and hence
the selection of a particular data structure stresses on
Traversing
Insertion
Deletion
Merging
Sorting
Searching
1.3 Algorithm
The step by step procedure to solve a problem is known as the
ALGORITHM. An algorithm is a well-organized, pre-arranged, and
defined computational module that receives some values or set of
values as input and provides a single or set of values as out put.
These well-defined computational steps are arranged in sequence,
which processes the given input into output.
An algorithm is said to be accurate and truthful only when it
provides the exact wanted output.
The efficiency of an algorithm depends on the time and space
complexities. The complexity of an algorithm is the function which
gives the running time and/or space in terms of the input size.
Steps Required to Develop an Algorithm
❖ Remainder Function
To find the remainder “mod” function is being used as
❖ Factorial of a Number
The product of the positive integers from 1 to n is known as the
factorial of n and it is denoted as n!.
Algorithemic Notations
While writing the algorithm the comments are provided with in [
].
The assignment should use the symbol “: =” instead of “=”
For Input use Read : variable name
For output use write : message/variable name
The control structures can also be allowed to use inside an algorithm
but their way of approaching will be some what different as
Simple If
If condition, then:
Statements
[end of if structure]
If...else
If condition, then:
Statements
Else :
Statements
[end of if structure]
If...else ladder
If condition1, then:
Statements
Else If condition2, then:
Statements
Else If condition3, then:
Statements
…………………………………………
…………………………………………
…………………………………………
Else If conditionN, then:
Statements
Else:
Statements
[end of if structure]
LOOPING CONSTRUCT
Repeat for var = start_value to end_value by
step_value
Statements
[end of loop]
OUTPUT
1 3 5 7 9
A fixed part that includes space for the code, space for simple
variables and fixed size component variables, space for
constants, etc.
A variable part that consists of the space needed by component
variables whose size is dependent on the particular problem
instance being solved, and the stack space used by recursive
procedures.
Time Complexity
The time complexity of a program is the amount of computer time it
needs to run to completion. The time complexity is of two types such
as
Compilation time
Runtime
Best Case
Generally, most of the algorithms behave sometimes in best case. In
this case, algorithm searches the element for the first time by itself.
For example: In linear search, if it finds the element for the first time
by itself, then it behaves as the best case. Best case takes shortest
time to execute, as it causes the algorithms to do the least amount of
work.
Worst Case
In worst case, we find the element at the end or when searching of
elements fails. This could involve comparing the key to each list
value for a total of N comparisons.
For example in linear search suppose the element for which
algorithm is searching is the last element of array or it is not
available in array then algorithm behaves as worst case.
Average Case
Analyzing the average case behavior algorithm is a little bit complex
than the best case and worst case. Here, we take the probability with
a list of data. Average case of algorithm should be the average
number of steps but since data can be at any place, so finding exact
behavior of algorithm is difficult. As the volume of data increases, the
average case of algorithm behaves like the worst case of algorithm.
Introduction
An important question is: How efficient is an algorithm or piece of
code? Efficiency covers lots of resources, including:
CPU (time) usage
Memory usage
Disk usage
Network usage
All are important but we will mostly talk about CPU time
Be careful to differentiate between:
Performance: how much time/memory/disk/... is actually used
when a program is running. This depends on the machine, compiler,
etc., as well as the code.
Complexity: how do the resource requirements of a program or
algorithm scale, i.e., what happens as the size of the problem being
solved gets larger. Complexity affects performance but not the other
way around. The time required by a method is proportional to the
number of “basic operations” that it performs. Here are some
examples of basic operations:
one arithmetic operation (e.g., +, *).
one assignment
one test (e.g., x == 0)
one read
one write (of a primitive type)
Note: As an example,
O(1) refers to constant time.
O(n) indicates linear time;
O(nk) (k fixed) refers to polynomial time;
O(log n) is called logarithmic time;
O(2n) refers to exponential time, etc.
n2 + 3n + 4 is O(n2), since n2 + 3n + 4 < 2n2 for all n > 10. Strictly
speaking, 3n + 4 is O(n2), too, but big-O notation is often misused to
mean equal to rather than less than.
The outer loop executes N times. Every time the outer loop executes,
the inner loop executes M times. As a result, the statements in the
inner loop execute a total of N * M times. Thus, the complexity is
O(N * M). In a common special case where the stopping condition of
the inner loop is j < N instead of j < M (i.e., the inner loop also
executes N times), the total complexity for the two loops is O(N2).
5. Statements with method calls:
When a statement involves a method call, the complexity of the
statement includes the complexity of the method call. Assume that
you know that method f takes constant time, and that method g takes
time proportional to (linear in) the value of its parameter k. Then the
statements below have the time complexities indicated.
f(k); // O(1)
g(k); // O(k)
has complexity (N2). The loop executes N times and each method call
g(N) is complexity O(N).
Examples
Q1. What is the worst-case complexity of the each of the
following code fragments?
Two loops in a row:
for (i = 0; i < N; i++) {
sequence of statements
}
for (j = 0; j < M; j++) {
sequence of statements
}
Answer: The first loop is O(N) and the second loop is O(M). Since
you do not know which is bigger, you say this is O(N+M). This can
also be written as O(max(N,M)). In the case where the second loop
goes to N instead of M the complexity is O(N). You can see this from
either expression above. O(N+M) becomes O(2N) and when you
drop the constant it is O(N). O(max(N,M)) becomes O(max(N,N))
which is O(N).
Q2. How would the complexity change if the second loop
went to N instead of M?
A nested loop followed by a non-nested loop:
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
sequence of statements
}
}
for (k = 0; k < N; k++) {
sequence of statements
}
Answer: The first set of nested loops is O(N2) and the second loop is
O(N). This is O(max(N2,N)) which is O(N2).
Q3. A nested loop in which the number of times the inner
loop executes depends on the value of the outer loop index:
for (i = 0; i < N; i++) {
for (j = i; j < N; j++) {
sequence of statements
}
}
1.8 Questions
1. What is data structure?
2. What are the types of operations that can be performed with
data structure?
3. What is asymptotic notation and why is this used?
4. What is complexity and its type?
5. Find the complexity of 3n2 + 5n.
6. Distinguish between linear and non-linear data structure.
7. Is it necessary is use data structure in every field? Justify your
answer.
2
Review of Concepts of ‘C++’
2.1 Array
Whenever we want to store some values then we have to take the help of a
variable, and for this we must have to declare it before its use. If we want to
store the details of a student so for this purpose we have to declare the
variables as
char name [20], add[30] ;
int roll, age, regdno ;
float total, avg ;
etc……
for a individual student.
If we want to store the details of more than one student than we have to
declare a huge amount of variables and which are too much difficult to access
it. I.e/ the programs length will increased too faster. So it will be better to
declare the variables in a group. I.e/ name variable will be used for more than
one student, roll variable will be used for more than one student, etc.
So to declare the variable of same kind in a group is known as the Array and
the concept of array is used for this purpose only.
Definition: The array is a collection of more than one element of same kind
with a single variable name.
Types of Array:
The arrays can be further classified into two broad categories such as:
Initialization:
The array is also initialized just like other normal variable except that we have
to pass a group of elements with in a chain bracket separated by commas.
Ex : int x[5]= { 24,23,5,67,897 } ;
In the above statement x[0] = 24, x[1] = 23, x[2]=5, x[3]=67,x[4]=897
Retrieving and Storing Some Value From/Into the Array
Since array is a collection of more than one elements of same kind so while
performing any task with the array we have to do that work repeatedly.
Therefore while retrieving or storing the elements from/into an array we must
have to use the concept of looping.
Ex: Write a Program to Input 10 Elements Into an Array and
Display Them.
#include<iostream.h>
void main()
{
int x[10],i;
;
cout<<“\nEnter 10 elements into the array”;
for(i=0 ; i<10; i++)
cin>>x[i];
cout<<“\n THE ENTERED ARRAY ELEMENTS ARE :”;
for(i=0 ; i<10; i++)
cout<<” “<<x[i];
}
OUTPUT
Enter 10 elements into the array
12
36
89
54
6
125
35
87
49
6
THE ENTERED ARRAY ELEMENTS ARE : 12 36
89 54 6 125 35 87 49 6
Ex : int x[3][4];
In the above example x is the two dimensional array which has the capacity to
store (3x4) 12 elements. The individual number of elements are
INITIALIZATION
The array can also be initialized as like one dimensional array.
OR
OUTPUT
Enter a number 5
Enter a number 7
Enter a number 9
Enter a number 2
Enter a number 6
Enter a number 8
Enter a number 12
Enter a number 24
Enter a number 7
THE ENTERED MATRIX IS
5 7 9
2 6 8
12 24 7
Sum of the lower triangular matrix is 56
OUTPUT
Enter a string Hello
THE ENTERED STRING IS Hello
OR
This process of Input is not preferable because forcibly we are
bound to input the 10 characters, not less than 10 or above 10
characters.
#include<iostream.h>
void main()
{
char x[20];
int i;
cout<<"\nEnter a string";
for(i=0;i<10;i++)
cin>>x[i];
OR
#include<iostream.h>
void main()
{
char x[20];
int i;
cout<<"\nEnter a string";
gets(x);
cout<<"\n THE ENTERED STRING IS ";
for(i=0; x[i]!=’\0’;i++)
cout<<x[i];
}
OUTPUT
Enter a string Hello
THE ENTERED STRING IS Hello
Example – 2
Write a program to input a string and count how many vowels are
in it.
#include<iostream.h>
void main()
{
char x[20];
int i,count=0;
cout<<"\n Enter a string";
gets(x);
cout<<"\n The entered string is"<<x;
for(i=0; x[i]!='\0';i++)
if(toupper(x[i])=='A' || toupper(x[i])=='E'
|| toupper(x[i])=='I' || toupper (x[i])=='O' ||
toupper(x[i))=='U')
count++;
cout<<"\n The string"<<x<< "having"<<count<<"numbers
of vowels";
}
OUTPUT
Enter a string Wel Come
The entered string is Wel Come
The string Wel Come having 3 numbers of vowels.
Example :
Write a program to find out the length of a string.
#include<iostream.h>
void main()
{
char x[20];
int i,len=0;
cout<<"\n Enter a string";
gets(x);
for(i=0;x[i]!='\0';i++)
len++;
cout<<"\n THE LENGTH OF"<<x<<"IS"<<len;
}
OUTPUT
Enter a string hello India
THE LENGTH OF hello India IS 11
OR
#include<iostream.h>
void main()
{
char x[20];
int i;
cout<<"\n Enter a string";
gets(x);
for(i=0;x[i]!='\0';i++) ;
cout<<"\n THE LENGTH OF"<<x<<"IS"<<len;
}
OUTPUT
Enter a string hello India
THE LENGTH OF hello India IS 11
String Manipulation
The strings cannot be manipulated with the normal operators, so to have some
manipulation we have to use the help of certain string handling functions. ’C’-
language provides a number of string handling functions amongst them the
most popularly used functions are
a. Strlen()
b. Strrev()
c. Strcat()
d. Strcmp()
e. Strcpy()
f. Strupr()
g. Strlwr()
These functions prototypes are declared inside the header file string.h
❖ Strlen()
Purpose : Used to find out the length of a string.
Syntax : integer_variable = strlen(string);
❖ Strrev()
Purpose : Used to find out the reverse of a string.
Syntax : strrev(string);
❖ Strcat()
Purpose: Used to concatenate (Join) two strings. It will append the
source string at the end of the destination. The length of the destination
will be the length of source + length of destination
Syntax: strcat(destination,source);
❖ Strcmp()
Purpose: Used to compare two strings.
Process: The string comparison always starts with the first character in
each string and continuous with subsequent characters until the
corresponding characters differ or until the end of a string is reached.
2.2 Function
Definition: One or more than one statements combined together to form a
block with a particular name and having a specific task.
The functions in ‘C’ are classified into two types as
The library functions are already comes with the ‘C’ compiler(Language).
Ex : printf(), scanf(), gets(), clrscr(), strlen() etc.
The user defined functions are defined by the programmer when ever
required.
Parts of a Function
A function has generally three parts as
1. Declaration (Specifies that how the function will work, it prepares only
the skeleton of the function)
2. Call [It call the function for execution]
3. Definition [It specifies the work of the function i./ it is the body part of the
function]
Ex:
int sum(int p, int q)
{
int z;
z = p+q;
return(z);
}
Ex:
void sum(int x, int y)
{
cout<<"\nSum = "<<x+y;
}
Ex:
void sum()
{
int x,y;
cout<<"\n Enter two numbers";
cin>>x>>y;
cout<<"\nSum = "<<x+y;
}
OUTPUT
Enter two numbers 5
6
Addition of 5 and 6 is 11
Category – 2
OUTPUT
Enter two numbers 5
6
Addition is 11
Category – 3
OUTPUT
Enter two numbers 5
6
Addition of 5 and 6 is 11
Category – 4
OUTPUT
Enter two numbers 5
6
Addition of 5 and 6 is 11
OUTPUT
Enter two numbers 5
6
Addition of 5 and 6 is 11
If a function is to use arguments, it must declare variables that accept the
values of the arguments. These variables are called the formal parameters
of the function.
The formal parameters behave like other local variables inside the function
and are created upon entry into the function and destroyed upon exit.
While calling a function, there are two ways that arguments can be passed to a
function:
Call Description
Type
Call by This method copies the actual value of an argument into the formal
value parameter of the function. In this case, changes made to the
parameter inside the function have no effect on the argument.
Call by This method copies the address of an argument into the formal
pointer parameter. Inside the function, the address is used to access the
actual argument used in the call. This means that changes made to
the parameter affect the argument.
Call by This method copies the reference of an argument into the formal
reference parameter. Inside the function, the reference is used to access the
actual argument used in the call. This means that changes made to
the parameter affect the argument.
By default, C++ uses call by value to pass arguments. In general, this means
that code within a function cannot alter the arguments used to call the
function and above mentioned example while calling max() function used the
same method.
result = a + b;
return (result);
}
int main ()
{
// local variable declaration:
int a = 100;
int b = 200;
int result;
// calling a function to add the values.
result = sum(a, b);
cout << "Total value is :" << result << endl;
return 0;
}
When the above code is compiled and executed, it produces following result:
Total value is :300
Total value is :120
OUTPUT
X=0
X=0
X=0
#include<stdio.h>
void main()
{
void change();
change();
change();
change();
}
Void change()
{
static int x;
printf("\n X= %d",x);
x++;
}
OUTPUT
X=0
X=1
X=2
2.3 Pointer
The pointer is a variable which can store the address of another variable.
Whatever changed with the value of the variable with the help of the pointer
that will directly effect to it.
Example :(IN C)
WRITE A PROGRAM TO INPUT A NUMBER AND DISPLAY IT.
#include<iostream.h>
void main()
{
int *p,x;
p=&x;
printf(“\n Enter a number”);
scanf(“%d”,&x);
OUTPUT
Enter a number 5
OUTPUT
Enter a number 5
THE VALUE OF X(THROUGH POINTER) IS 5
THE VALUE OF X IS 5
NOTE : Pointer means the address so we can perform any type of operation
with *p (value at address)
OUTPUT
Enter a number 5
Factorial is 120
int main ()
{
int *ptr = NULL;
return 0;
}
When the above code is compiled and executed, it produces the following
result:
The value of ptr is 0
Thus, if all unused pointers are given the null value and you avoid the use of a
null pointer, you can avoid the accidental misuse of an uninitialized pointer.
Many times uninitialized variables hold some junk values and it becomes
difficult to debug the program.
2.4 Structure
A structure is a collection of data items(fields) or variables of different data
types that is referenced under the same name. It provides convenient means of
keeping related information together.
DECLARATION
struct tag_name
{
Data type member1 ;
Data type member2;
…………………………
…………………………
…………………………
};
The keyword struct tells the compiler that a structure template is being
defined, that may be used to create structure variables. The tag_name
identifies the particular structure and its type specifier. The fields that
comprise the structure are called the members or structure elements. All
elements in a structure are logically related to each other.
Let us consider an employee data base, which consists of the fields like name,
age, and salary, so for this the corresponding structure declaration will be
struct emp
{
char name[25];
int age;
float salary;
};
Here the keyword struct defines a structure to hold the details of the employee
and the tag_name emp is the name of the structure.
Over all struct emp is a user defined data type.
So to use the members of this structure we must have to declare the variable of
struct emp type and the structure variable declaration is as same as the normal
variable declaration which takes the form as
struct tag_name variable_name;
Ex : struct emp e;
Here e is a structure variable which has the ability to hold name, age, and
salary and to access these individual members of the structure the way is
Structure_variable . member_name;
i.e/ To access name,age,salary the variable will be e.name,e.age,e.salary
Example: WAP TO INPUT THE NAME,AGE AND SALARY OF A
EMPLOYEE AND DISPLAY.
#include<iostream.h>
struct emp // CREATION OF STRUCT EMP DATA TYPE
{
char name[25];
int age;
float salary;
};
void main()
{
struct emp e; //Declaration of the
structure variable
cout<<"\n Enter the name,age and salary";
gets(e.name); //Input the name
cin>>e.age>>e.salary; // Input the age
and salary
OUTPUT
Enter the name ,age and salary
H.Narayanan 56
72000
NAME IS H.Narayanan
AGE IS 56
SALARY IS 72000.000000
The above discussed structure is usually used in ‘C’ but the ‘C++’ provides its
structure with a little bit modification with the structure of ‘C’ that is in C++
we may also store the member functions as a member of it.
Ex: WAP TO INPUT A NUMBER AND DISPLAY IT by using
FUNCTION
No doubt that this program is not efficiently used with the structure because
the structure is used when there is a requirement to handle more than one
element of different type. But in the above program only single variable is to
be used but for easy understanding the difference of structure in ‘c’ and
structure in ‘c++’ this one is better.
IN ‘C’
#include<stdio.h>
struct print
{
int x;
} ;
void main()
{
struct print p;
void display(struct print);
printf("\n Enter the number");
scanf("%d",&p.x);
display(p);
}
void display(struct print p)
{
printf("THE ENTERED NUMBER IS %d",p.x);
}
OUTPUT
Enter the number 23
THE ENTERED NUMBER IS 23
IN C++
#include<iostream.h>
struct print
{
int x;
void display( )//Arguments are not required
because both x and display() are in the same scope
{
cout<<"\n Enter the number";
cin>>x;
cout<<"THE ENTERED NUMBER IS "<<x;
}
} ;
void main()
{
print p;//In C++ to declare the structure variable
struct is not mandatory
p.display();
}
OUTPUT
Enter the number 23
THE ENTERED NUMBER IS 23
Observe that the C++-structure is better than the C-Structure but it has also
some limitation. That means the above program can also be written as
Inside the void main() instead of calling the function as p.display() we may
also replace it as
cout<<”Enter the number”;
cin>>p.x;
cout<<”THE ENTERED NUMBER IS”<<p.x;
Which is not a small mistake it can make frustrate to the programmer that
even if the programmer provides a function to does the work but instead of
using that we are using according to our logic. Here the importance of the
designer is Nill and this happens since the structure allow all of its
members to use any where of the program. But if the data member ‘x’ will
not allowed to use inside the main() then we are bound to use the function
which is provided by the programmer.
So Finally the main drawback is that structure does not allow any
restriction to its members.
To overcome this problem C++ implements a new, abundantly used data type
as “class” which is very much similar to the structure but it allows the security
of members i.e/the programmer has a control over its members.
NOTE: C++ structure also provides data hiding and encapsulation but other
properties like the Inheritance, Polymorphism are not supported by it. So to
overcome this C++ introduces the CLASS.
Now you can use Books directly to define variables of Books type without using
struct keyword. Following is the example:
Books Book1, Book2;
You can use typedef keyword for non-structs as well as follows:
typedef long int *pint32;
pint32 x, y, z;
x, y, and z are all pointers to long ints
UNION
The UNION is also a user defined data type just like the structure, which can
store more than one element of different data types. All the operations are
same as the structure. The only difference between the structure and union is
based upon the memory management i.e/ the structure data type will occupies
the sum of total number of bytes occupied by its individual data members
where as in case of union it will occupy the highest number of byte occupied by
its data members.
Example 7.11
Write a program to demonstrate the difference between the structure and
Union.
#include<iostream.h>
struct std
{
char name[20],add[30];
int roll,total;
float avg;
};
union std1
{
char name[20],add[30];
int roll,total;
float avg;
};
void main()
{
struct std s;
union std1 s1;
cout<<”\nThe no.of bytes occupied by the structure
is”<<sizeof(struct std));
cout<<”\nThe no.of bytes occupied by the union
is”<<sizeof(union std1));
}
OUTPUT
The no.of bytes occupied by the structure is 58
The no.of bytes occupied by the structure is 30
NOTE: While using UNION we have used the values of the variables
immediately before entering any value to any member. Because the union
shares a single memory area for all the data members.
2.5 Questions
1. What are the advantages of unions over structures?
2. What is a pointer and its types?
3. What is the difference between Library functions and User-defined
functions?
4. What is the difference between call by value and call by reference.
5. What is the difference between array and pointer?
6. Is it better to use a macro or a function?
7. What is a string?
8. Discuss different types of storage class specifiers.
9. Discuss local and global variables.
10. Is it of benefit to use structure or array? Justify your answer.
3
Sparse Matrix
1. Triplet Representation
2. Linked Representation
OUTPUT
//ask user about the numbe o3f ows and columns sparse
matx
cout<<”\nENTER HOW MANY ROWS AND COLUMNS”;
//read row and col
cin>>row>>col;
//loop to read the normal matrix
for(i=0;i<row;i++)
for(j=0;j<col;j++)
{
cout<<endl<<”Enter a number”;
cin>>arr[i][j];
}
//loop to print the normal matrix that read from user
cout<<”\nTHE ENTERED ARRAY ELEMENTS ARE\n”;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
cout<<setw(4)<<arr[i][j];
cout<<endl;
}
OUTPUT
3.5 Why to Use Sparse Matrix Instead of
Simple Matrix?
Storage: There are lesser non-zero elements than zeros and
thus lesser memory can be used to store only those non-zero
elements.
Computing time: Computing time can be saved by logically
designing a data structure traversing only non-zero elements.
2. In Data Preparation
Sparse matrices are often seen in encoding schemes, which are used
for data preparation.
Examples:
3.8 Questions
1. What is a sparse Matrix?
2. Write some implementation areas of sparse matrix.
3. How to represent sparse matrix.
4. Differentiate with suitable example about the representation of
sparse matrix.
5. Is it more beneficial to use sparse matrix than dense matrix?
Explain your answer.
6. What are the limitations of sparse matrix?
7. Specify a few limitations of sparse matrix.
4
Concepts of Class
Member Function
A member function of a class is a function that has its definition or
its prototype within the class definition like any other variable. It
operates on any object of the class of which it is a member, and has
access to all the members of a class for that object.
Example :
class print
{
private:
int x;
public :
void display()
{
cout<<“\n Enter the number”;
cin>>x;
cout<<“THE ENTERED NUMBER IS ”<<x;
}
};
endl
setw()
setfill()
dec
oct
hex
setprecision()
These manipulators are defined inside the <iomanip.h> so before its
use we must have to include<iomanip.h>
endl
This manipulator allows a new line. It does the same work as “\n”.
Ex : cout<<”HELLO”<<endl<<”WEL COME”;
OUTPUT
HELLO
WEL COME
setw()
This manipulator is used to allow some gap in between two numbers.
Ex : int x=5,y=4
cout<<x<<setw(5)<<y;
OUTPUT
5_ _ _ _ 4 (_ indicates the white space)
setfill()
This manipulator is used to allow to fill the gap by a character which
is provided by the setw() manipulator.
Ex :
int x=5,y=4;
cout<<setfill(‘$’);
cout<<x<<setw(5)<<y;
OUTPUT
5$$$$4
Dec,oct,hex
These manipulators are used to display the integer in different base
values.
Dec : Display the number in integer format
Oct : Display the number in Octal format
Hex : Display the number in Hexadecimal format
Ex :
void main()
{
int x = 14;
cout<<”DECIMAL ”<<dec<<x;
cout<<endl<<”OCTAL”<<oct<<x;
cout<<endl<<”HEXADECIMAL”<<hex<<x;
}
OUTPUT
DECIMAL 14
OCTAL 16
HEXADECIMAL e
Setprecision()
This manipulator is used to controls the number of digits to be
displayed after the decimal place of a floating point number.
Ex :
float x=5.23456;
cout<<setprecision(2)<<x;
cout<<endl<<setprecision(0)<<x;
cout<<endl<<setprecision(6)<<x;
OUTPUT
5.23
5.23456
5.23456
Example
Write a program to input the detail of 5 students and display them.
class student
{
char name[20],add[30];
int roll,age;
public :
void input();
void print();
};
public :
void input();
void check();
};
void prime :: input()
{
cout<<”Enter the number”;
cin>>x;
}
void prime :: check()
{
int i;
for(i=2 ; i<=x;i++)
{
if(x%i==0)
break;
}
if(i==x || x==1)
cout<<”PRIME”;
else
cout<<”NOT PRIME”;
}
void main()
{
prime *p;
p->input();
p->check();
}
Example
WAP to find out the GCD of two numbers
#include<iostream.h>
class GCD
{
private :
int a,b;
public :
void input();
void find();
};
Syntax :
inline return_type function_name(argument list….)
{
Body of function;
Return(value/variable/expression);
}
public :
data member ;
member function();
protected :
data member ;
member function();
};
class B
{
private :
data member ;
member function();
return_type function_name (A obj);
public :
data member ;
member function();
return_type function_name (A obj);
protected :
data member ;
member function();
return_type function_name (A obj);
};
Example
#include<iostream.h>
#include<iomanip.h>
#include<stdio.h>
class std
{
friend class mark;
private:
char name[20],add[20];
int age,roll,m[5],total;
float avg;
public:
void input();
};
class mark
{
public:
void result(std obj);
};
void std :: input()
{
total=0;
cout<<”Enter the name and address”;
gets(name);
gets(add);
cout<<”Enter the age,roll”;
cin>>age>>roll;
cout<<”Enter the marks in 5 subjects”;
for(int i=0;i<5;i++)
{
cin>>m[i];
total=total+m[i] ;
}
avg= float(total)/5;
}
void mark :: result(std obj)
{
cout<<endl<<”NAME IS “<<obj.name;
cout<<endl<<”ADDRESS “<<obj.add;
cout<<endl<<”AGE IS “<<obj.age;
cout<<endl<<”ROLL IS “<<obj.roll;
for(int i=0;i<5;i++)
cout<<endl<<”MARK “<<i+1<<” IS “<<obj.m[i];
cout<<endl<<”TOTAL IS “<<obj.total;
cout<<endl<<”AVERAGE IS “<<obj.avg;
if(obj.avg>=50)
cout<<endl<<”P A S S”;
else
cout<<endl<<”F A I L”;
}
void main()
{
std obj;
mark obj1;
obj.input();
obj1.result(obj);
}
class nameN
{
private :
data member;
member function();
public:
data member;
member function();
friend return_type function_name(name1 obj1,name2 obj2…
nameN objn);
protected :
data member;
member function();
};
class name1
{
private :
data member;
member function();
public:
data member;
member function();
friend return_type function_name(name1 obj1,name2 obj2…
nameN objn);
protected :
data member;
member function();
};
………………………………………………………………………………..
………………………………………………………………………………..
………………………………………………………………………………..
class nameN-1
{
private :
data member;
member function();
public:
data member;
member function();
friend return_type function_name(name1 obj1,name2 obj2…
nameN objn);
protected :
data member;
member function();
};
Example
#include<iostream.h>
class A;
class B;
class C
{
private:
int x;
public:
void input();
friend void average(A obj,B obj1,C obj2);
};
class A
{
private:
int y;
public:
void input();
friend void average(A obj,B obj1,C obj2);
};
class B
{
private:
int z;
public:
void input();
friend void average(A obj,B obj1,C obj2);
};
void C :: input()
{
cout<<”Enter a number”;
cin>>x;
}
void A :: input()
{
cout<<»Enter a number»;
cin>>y;
}
void B :: input()
{
cout<<”Enter a number”;
cin>>z;
}
In the above case the 3 copies of the data_member ‘x’ will be created
for the three objects obj,obj1,obj2. So if we will change the ‘x’ through
obj then that will not affect the ‘x’ of obj1 and also obj2.
class demo
{
private:
static int x;
};
int demo :: x;
void main()
{
demo obj,obj1,obj2;
……………………
…………………..
}
In this case instead of creating three copies it will create a single copy
of the data_member ‘x’ for all the objects and that will be shared by
the objects. So if we change the value of the data_member through
obj than that will be effect to obj1 and obj2.
Example
#include<iostream.h>
class demo
{
private:
static int x;
public:
void change();
void display();
};
void demo :: display()
{
cout<<x;
}
void demo :: change()
{
x++;
}
int demo :: x=5;
void main()
{
demo obj,obj1,obj2;
obj.display();
obj1.display();
obj2.display();
obj.change();
obj.display();
obj1.display();
obj2.display();
}
OUTPUT 555666
The keyword static can also be used with the member function. The
speciality with the function is that it can only use the static data
members and can be called by the class name as
class_name :: function_name();
#include<iostream.h>
class demo
{
static int x;
public :
static void print();
};
void demo :: print()
{
cout<<endl<<++x;
}
int demo :: x=5;
void main()
{
demo obj;
demo :: print();
obj.print();
}
OUTPUT 6 7
Empty Constructors
Default constructors
Parameterized Constructors
Copy constructors
Example
#include<iostream.h>
class hello
{
private:
int x;
public :
hello();
void display();
};
hello :: hello()
{
x=5;
}
void hello :: display()
{
cout<<endl<<x;
}
void main()
{
hello obj,obj1,obj2; //constructors are called
obj.display();
obj1.display();
obj2.display();
}
OUTPUT
5
5
5
Example
#include<iostream.h>
#include<conio.h>
#include<iomanip.h>
class fibo
{
private:
int a,b,c,n;
public :
fibo(int);
void generate();
};
fibo :: fibo(int x)
{
a=0;
b=1;
c=a+b;
n=x;
}
void fibo :: generate()
{
cout<<”THE FIBONACCI SERIES NUMBERS ARE”;
cout<<endl<<a<<setw(4)<<b;
for(int i=3;i<=n;i++)
{
c=a+b;
cout<<setw(4)<<c;
a=b;
b=c;
}
}
void main()
{
int n;
cout<<”Enter how many digits U want to print”;
cin>>n;
fibo obj(n);
clrscr();
obj.generate();
}
OUTPUT
Enter how many digits U want to print 8
THE FIBONACCI SERIES NUMBERS ARE
0 1 1 2 3 5 8 13
fibo :: fibo(int x)
{
a=0;
b=1;
c=a+b;
n=x;
}
void fibo :: generate()
{
cout<<”THE FIBONACCI SERIES NUMBERS ARE”;
cout<<endl<<a<<setw(4)<<b;
for(int i=3;i<=n;i++)
{
c=a+b;
cout<<setw(4)<<c;
a=b;
b=c;
}
}
void main()
{
int n;
cout<<”Enter how many digits U want to print”;
cin>>n;
fibo obj(n);
obj.generate(); }
OUTPUT
Enter how many digits U want to print 8
THE FIBONACCI SERIES NUMBERS ARE
0 1 1 2 3 5 8 13
4.11.2 Destructor
A destructor is also a member function of the class which is used for
the destruction of the objects which are created by a constructor.
That is this is used for the de-allocation purpose. The declaration of
the destructor is as same as the constructor except that the
destructor is declared with the tiled(~) symbol and it does not have
any return type as well as it does not have any argument.
The destructors are also called automatically. The keyword “virtual”
cam be used with destructor.
Ex :
#include<iostream.h>
#include<conio.h>
class demo
{
public:
demo()
{
cout<<”CONSTRUCTOR IS CALLED”;
}
void input()
{
cout<<endl<<”HELLO”;
}
~demo()
{
cout<<endl<<”DESTRUCTOR IS CALLED”;
getch();
}
};
void main()
{
demo obj;
obj.input();
}
OUTPUT
CONSTRUCTOR IS CALLED
HELLO
DESTRUCTOR IS CALLED
delete operator
delete var ; //for single memory cell
delete [ ] var; // for an array
Example :
Wap to enter n number of elements into an array and
display them.
#include<iostream.h>
#include<iomanip.h>
void main()
{
int n;
cout<<”Enter how many elements to be handle”;
cin>>n;
int *p = new int[n];
for(int i=0;i<n;i++)
{
cout<<”Enter a number”;
cin>>*(p+i);
}
cout<<”THE ELEMENTS ARE”;
for(i=0;i<n;i++)
cout<<setw(5)<<*(p+i);
delete []p;
}
Example :
#include<iostream.h>
class even
{
private:
int n;
public:
void input();
void check();
};
void even :: input()
{
cout<<”Enter a number”;
cin>>this->n;
}
void even :: check()
{
cout<<”THE ADDRESS OF OBJECT IS “<<this;
if(this->n %2==0)
cout<<endl<<this->n<<”IS EVEN”;
else
cout<<endl<<this->n<<”IS NOT EVEN”;
}
void main()
{
even obj;
obj.input();
obj.check();
}
OUTPUT
Enter a number 5
THE ADDRESS OF OBJECT IS 0x8fa7fff4
5 IS NOT EVEN
class b
{
public :
a obj;
void print()
{
cout<<"INDIA";
}
};
void main()
{
b B;
B.print();
B.obj.input();
}
OR
#include<iostream.h>
class a
{
private:
int x;
public :
void check();
class b
{
private:
int y ;
public:
void print();
};
};
void a :: check()
{
cout<<"Enter the number";
cin>>x;
if(x>=0)
cout<<endl<<"+VE";
else
cout<<endl<<"-VE";
}
void a::b::print()
{
cout<<endl<<"Enter the number";
cin>>y;
if(y%2==0)
cout<<endl<<"EVEN";
else
cout<<endl<<"ODD";
}
void main()
{
a obj;
a::b obj1;
obj.check();
obj1.print(); }
4.15 Questions
1. Define features of object-oriented paradigm.
2. What are the access specifiers used in class?
3. Differentiate between inline and macro.
4. What is the benefit of using friend function?
5. What are the types of constructors?
6. What is dynamic memory allocation?
7. What is the use of this pointer?
8. What are the types of manipulators in c++?
9. Discuss features of static data member and static member
functions.
10. Differentiate between structure and class.
5
Stack
5.1 STACK
Stack is a linear data structure which follows the principle of LIFO
(Last in First Out). In other words we can say that if the LIFO
principle is implemented with the array than that will be called as the
STACK.
}
int main()
{
string str;
int i;
cout<<”\n ENTER THE EXPRESSION”;
cin>>str;
for(i=0;str[i]!=’\0’;i++)
{
if(str[i]==’(‘||str[i]==’[‘||str[i]==’{‘)
push(str[i]);
if(str[i]== ‘)’|| str[i]==’]’ || str[i]==’}’)
pop(str[i]);
}
if(top == -1)
cout<<”\n EQUATION IS CORRECT”;
else
cout<<”\n INVALID EXPRESSION”;
}
OUTPUT
WAP TO REVERSE A STRING BY USING STACK.
#include<iostream>
#include<string.h>
using namespace std;
// Driver code
int main()
{
char str[50];
cout<<endl<<”Enter a string”;
gets(str);
Reverse(str);
cout << “Reversed string is “ << str;
return 0;
}
Output
EXAMPLE :
Convert A + B – (C * D – E + F ^ G) + (H + I * J) into
POSTFIX by using STACK.
ARRAY STACK POSTFIX
( (
A ( A
+ (+ A
B (+ AB
- (- AB +
( (-( AB+
C (-( AB+C
* (-(* AB+C
D (-(* AB+CD
- (-(- AB+CD*
E (-(- AB+CD*E
+ (-(+ AB+CD*E-
F (-(+ AB+CD*E-F
^ (-( + ^ AB+CD*E-F
G (-( + ^ AB+CD*E-FG
) (- AB+CD*E-FG^+
+ (+ AB+CD*E-FG^+-
( (+( AB+CD*E-FG^+-
H (+( AB+CD*E-FG^+-H
+ (+(+ AB+CD*E-FG^+-H
I (+(+ AB+CD*E-FG^+-HI
* (+(+* AB+CD*E-FG^+-HI
J (+(+* AB+CD*E-FG^+-HIJ
) (+ AB+CD*E-FG^+-HIJ*+
) AB+CD*E-FG^+-HIJ*++
Convert A + B – (C * D – E + F ^ G) + (H + I * J) into
PREFIX by using STACK.
ARRAY STACK PREFIX
( (
( ((
J (( J
* ((* J
I ((* JI
+ (( + JI*
H (( + JI*H
) ( JI*H+
+ (+ JI*H+
( (+( JI*H+
G (+( JI*H+G
^ ( + (^ JI*H+G
F ( + (^ JI*H+GF
+ (+(+ JI*H+GF^
E (+(+ JI*H+GF^E
- (+(+- JI*H+GF^E
D (+(+- JI*H+GF^ED
* ( + ( + -* JI*H+GF^ED
C (+(+-* JI*H+GF^EDC
) (+ JI*H+GF^EDC*-+
- (+- JI*H+GF^EDC*-+
B (+- JI*H+GF^EDC*-+B
+ (+-+ JI*H+GF^EDC*-+B
A (+-+ JI*H+GF^EDC*-+BA
) JI*H+GF^EDC*-+BA+-+
FINAL RESULT I.E/ PREFIX IS +-+AB+-*CDE^FG+H*IJ
RESULT : 18
5.5 Programming Implementations of STACK
Wap to perform the PUSH,POP, and TRAVERSE operation with
the STACK.
#include<iostream>
#include<stdlib.h>
using namespace std;
static int *s,size,top=-1;
//method to push an integer into stack
void push(int no)
{
if(top == size-1)
cout<<”\n STACK OVERFLOW”;
else
{
top = top+1;
*(s+top) = no;
}
}
//method to pop an element from stack
void pop()
{
if(top == -1)
cout<<”\n STACK UNDERFLOW”;
else
{
cout<<*(s+top)<< “ IS DELETED”;
--top;
}
}
// method to display the elements of the stack
void traverse()
{
int i;
if(top == -1)
cout<<”\n STACK IS EMPTY”;
else
for(i = top; i>=0;i--)
cout<<*(s+i)<<” “;
}
//driver program
int main()
{
int opt;
cout<<”\n Enter the size of the stack”;
cin>>size; //ask user about the size of stack
s= (int *)malloc(size * sizeof(int)); //dynamically
allocate memory for stack
// infinite loop to handle the operations of stack
while(1)
{
cout<<”\n Enter the choice”;
cout<<”\n 1.PUSH 2. POP 3. DISPLAY 0. EXIT”;
cin>>opt;
if(opt==1)
{
cout<<”\n Enter the number to insert”;
cin>>opt;
push(opt);
}
else
if(opt==2)
pop();
else
if(opt==3)
traverse();
else
if(opt==0)
exit(0);
else
cout<<”\n INVALID CHOICE”;
}
}
OUTPUT
STACK OPERATIONS USING STL
#include <iostream>
#include <stack>
using namespace std;
int main ()
{
stack <int> myStack;
int n,opt;
while(1)
{
cout<<endl<<”1. PUSH 2. POP 3. SIZE OF STACK 4.
TOP OF STACK 5. QUIT”;
cin>>opt;
if(opt==1)
{
cout<<endl<<”Enter a number to push”;
cin>>n;
myStack.push(n);
}
else
if(opt==2)
{
if(myStack.empty())
cout<<endl<<”Underflow”;
else
{
myStack.pop();
cout<<endl<<”Pop operation
completed successfully”;
}
}
else
if(opt==3)
{
cout<<endl<<myStack.size()<<” elements are
in
stack”;
}
else
if(opt==4)
{
if(myStack.empty())
cout<<endl<<”NO ELEMENTS ARE IN
STACK”;
else
cout<<endl<<”The top value is :
“<<myStack.top();
}
else
if(opt==5)
exit(0) ;
else
cout<<endl<<”Invalid choice”;
}
return 0;
}
OUTPUT
POSTFIX EVALUATION
#include<iostream>
using namespace std;
int stack[1000];//declare a stack of size 1000
static int top = -1;//set the value of top to -1 for empty
stack
//push method to push the characters of expression
void push(int x)
{
stack[++top] = x;
}
//pop method will delete the top element of stack
int pop()
{
return stack[top--];
}
//method to check the validity of expression
int isValid(char str[])
{
int i,cd=0,co=0;
for(i=0;i<(str[i]!=’\0’;i++)
{
if(str[i]>=’0’ && str[i]>=’9’)
cd++; //count number of digits
else
co++;//count number of operators
}
if(cd-co==1) //for a valid expression number of
digit - number of operator must be 1
return 1;//return 1 for valid expressison
else
return 0; //return 0 for invalid expression
}
//driver program
int main()
{
char postfix[1000];//declare the postfix as string
to store the expression
int a,b,c,val;
//read the postfix expression
cout<<”Enter the expression :“;
cin>>postfix;
if(!isValid(postfix))
{
cout<<endl<<”Invalid expression”;
exit(0);
}
OUTPUT
//pop method
char pop()
{
char i;
if(top==-1) //condition for empty stack
{
cout<<endl<<”Stack is empty”;
return 0;
}
else
{
i=str[top]; //store the popped operator
top=top-1;
}
return i;//return the popped operator
}
//method precedence
int preced(char c)
{
if(c==’/’||c==’*’)
return 3; //return 3 for * and /
if(c==’+’||c==’-’)
return 2; //return 2 for + and -
return 1;//return 1 for other operator if any
}
//method to convert the infix to postfix
void infx2pofx(char in[])
{
int l;
static int i=0,px=0;
char s,t;
char pofx[80];
l=strlen(in);//find the length of infix expression
while(i<l)
{
s=in[i];//extract one by one characer from infix
default : pofx[px++]=s;
break;
}
i=i+1;
}
while(top>-1)
{
t=pop();
pofx[px++]=t;
}
pofx[px++]=’\0’;
puts(pofx);
return;
}
//driver program
int main(void)
{
char ifx[50];
cout<<endl<<”Enter the infix expression”;
//read the infix expression
gets(ifx);
infx2pofx(ifx); //call to the method
return 0;
}
OUTPUT
//main() method
int main()
{
string post;
cout<<endl<<”Enter the postfix
expression”;
getline(cin,post) ;
cout << Infix2Postfix(post);
return 0;
}
OUTPUT
//driver program
int main()
{
string infix;//declare a string to store the infix
expression
cout<<endl<<”Enter an Infix expression(Provide a space
between operator and operands)”;
getline(cin,infix);//read the expression
cout<<endl<<infix<<” = “<<solve(infix);//print the result
return 0;
}
//returns the precedence of the operator
int priority(char op){
if(op == ‘+’||op == ‘-’)
return 1;
if(op == ‘*’||op == ‘/’)
return 2;
return 0;
}
if(ch==’+’)
return x + y;
else
if(ch==’-’)
return x - y;
else
if(ch==’*’)
return x * y;
else
if(ch==’/’)
return x / y;
}
OUTPUT
if((top-i+1) <0)
{
Printf(“\n OUT OF BOUND”);
}
else
{
Printf(“THE PEEPED ELEMENT IS %d”,
*(s+(top-i+1));
}
}
/* Definition of the display function */
void display()
{
int i;
if(top == -1)
{
printf(“\n Stack is empty”);
}
else
{
for(i = top; i >= 0; --i)
printf(“\n %d”, *(s+i) );
}
}
void main() /* Function main */
{ int no;
clrscr();
printf(“\nEnter the boundary of the stack”);
scanf(“%d”,&n);
stack = (int *)malloc(n * 2);
while(1)
{
printf(“WHICH OPERATION DO YOU WANT TO
PERFORM:\n”);
printf(“ \n 1. Push 2. PEEP 0. EXIT”);
scanf(“%d”,&no);
if(no==1)
{
printf(“\n Input the element to
push:”);
scanf(“%d”, &no);
push(no);
printf(“\n After inserting “);
display();
}
else
if(no==2)
{
peep();
display();
}
Else
if(no == 0)
exit(0);
else
printf(“\n INVALID OPTION”);
}
void main()
{
int no,q=0;
char ch;
int top= -1;
printf(“\nEnter the boundary of the stack”);
scanf(“%d”,&n);
stack = (int *)malloc(n * 2);
up:
printf(“WHICH OPERATION DO YOU WANT TO
PERFORM:\n”);
printf(“ \n Push->i\n update->p”);
printf(“\nInput the choice : “);
fflush(stdin);
scanf(“%c”,&ch);
printf(“Your choice is: %c”,ch);
if(tolower(ch)==’i’)
{
printf(“\n Input the element to
push:”);
scanf(“%d”, &no);
push(stack, no);
if(flag)
{
printf(“\n After inserting
“);
display(stack);
if(top == (n-1))
printf(“\n Stack is
full”);
}
else
printf(“\n Stack overflow
after
pushing”);
}
else
if(tolower(ch)==’p’)
{
no = update(stack);
if(flag)
{
printf(“\n The No %d is updated”,
no);
printf(“\n Rest data in stack is as
follows:\n”);
display(stack);
}
else
printf(“\n Stack underflow” );
}
opt:
printf(“\nDO YOU WANT TO OPERATE MORE”);
fflush(stdin);
scanf(“%c”,&ch);
if(toupper(ch)==’Y’)
goto up;
else
if(tolower(ch)==’n’)
exit();
else
{
printf(“\nINVALID CHARACTER...Try
Again”);
goto opt;
}
}
char pop()
{
char i;
if(top==-1)
{
printf(“\n The stack is Empty”);
getch();
return 0;
}
else
{
i=str[top];
top=top-1;
}
return i;
}
int preced(char c)
{
if(c==’$’||c==’^’)
return 4;
if(c==’/’||c==’*’)
return 3;
if(c==’+’||c==’-’)
return 2;
return 1;
}
switch(s)
{
case ‘)’ : push(s);break;
case ‘(‘ : t=pop();
while(t != ‘)’)
{
pofx[px]=t;
px=px+1;
t=pop();
}
break;
case ‘+’ :
case ‘-’ :
case ‘*’ :
case ‘/’ :
case ‘^’ :
while(preced(str[top])>preced(s))
{
t=pop();
pofx[px]=t;
px++;
}
push(s);
break;
default : pofx[px++]=s;
break;
}
i=i+1;
}
while(top>-1)
{
t=pop();
pofx[px++]=t;
}
pofx[px++]=’\0’;
strrev(pofx);
puts(pofx);
return;
}
int main(void)
{
char ifx[50];
printf(“\n Enter the infix expression ::”);
gets(ifx);
strrev(ifx);
//scanf(“%s”,ifx);
infx2prefx(ifx);
return 0;
}
5.6 Questions
1. In which principle does STACK work?
2. Write some implementations of stack.
3. What is polish and reverse polish notation?
4. Write a recursive program to check the validity of an expression
in terms of parenthesis ().{},[].
5. Write a recursive program to reverse a string using stack.
6. Explain structurally how stack is used in recursion with a
suitable example.
7. Convert (a+b*c) –(d/e^g) into equivalent prefix and postfix
expression.
8. What are overflow and underflow conditions in STACK?
9. Evaluate: 5,3,2,*,+,4,- using stack.
10. Write a recursive method to find the factorial of a number.
6
Queue
6.1 Queue
Queue is a linear data structure which follows the principle of FIFO.
In other words we can say that if the FIFO principle is implemented
with the array than that will be called as the QUEUE.
The most commonly implemented operations with the stack are
INSERT, DELETE.
Besides these two more operations can also be implemented with the
QUEUE such as PEEP and UPDATE.
During the INSERT operation we have to check the condition for
OVERFLOW and during the DELETE operation we have to check the
condition for UNDERFLOW.
The end at which the insertion operation is performed that will be
called as the REAR end and the end at which the delete operation is
performed is known as FRONT end.
Depending on the heaps the priority queue are also of two types such
as
Min Priority Queue
Max Priority Queue
The Set of operations for Max Priority Queue are
Insert
Minimum
Extract_Min
Decrease_Key
1. return A[1]
ALGORITHM EXTRACT-MAX(A)
1. If heapsize[A]<1
2. then Write : “Heap Underflow”
3. Max ←A[1]
4. A[1] ←A[heapsize[A]]
5. heapsize[A] ←heapsize[A]-1
6. Max_Heap(A,1)
7. retrun Max
ALGORITHM INCREASE-KEY(A,i,key))
1. if key <A[i]
2. then write “key is smaller than the current key”
3. A[i] ← key
4. while i > 1 and A[PARENT(i)]< A[i]
5. do exchange A[i] ↔ A[PARENT(i)]
6. i ← Parent(i)
ALGORITHM INSERT(A,key)
1. heapsize[A] ← heapsize[A] + 1
2. A[heapsize[A]] ← -∞
3. INCREASE-KEY(A, heapsize[A],key)
2. return A[1]
ALGORITHM EXTRACT-MIN(A)
8. If heapsize[A]<1
9. then Write : “Heap Underflow”
10. Max ←A[1]
11. A[1] ←A[heapsize[A]]
12. heapsize[A]←heapsize[A]-1
13. Max_Heap(A,1)
14. retrun Min
ALGORITHM DECREASE-KEY(A,i,key))
7. if key >A[i]
8. then write “key is greater than the current key”
9. A[i] ← key
10. while i > 1 and A[PARENT(i)]> A[i]
11. do exchange A[i] ↔ A[PARENT(i)]
12. i ← Parent(i)
ALGORITHM INSERT(A,key)
4. heapsize[A] ← heapsize[A] + 1
5. A[heapsize[A]] ← -∞
6. DECREASE-KEY(A, heapsize[A],key)
6.7 Programs
1. /* INSERTION AND DELETION IN A QUEUE ARRAY
IMPLEMENTATION */
# include<iostream>
#include<stdlib.h>
using namespace std;
int *q,size,front=-1,rear=-1;
void insert(int n)
{
if(rear ==size-1)
cout<<”\n QUEUE OVERFLOW”;
else
{
rear ++;
*(q+rear) = n ;
if(front == -1)
front = 0;
}
}
/* Function to delete an element from queue */
void Delete()
{
if (front == -1)
{
cout<<”\n Underflow”;
return ;
}
cout<<”\n Element deleted : “<<*(q+front);
if(front == rear)
{
front = -1;
rear = -1;
}
else
front = front + 1;
}
void display()
{
int i;
if (front == -1)
cout<<”\n EMPTY QUEUE”;
else
{
cout<<”\nTHE QUEUE ELEMENTS ARE”;
for(i = front ; i <= rear; i++)
cout<<”\t”<<*(q+i);
}
}
int main()
{
int opt;
cout<<”\n Enter the size of the QUEUE”;
cin>>size;
q= (int *)malloc(size * sizeof(int));
while(1)
{
cout<<”\n Enter the choice”;
cout<<”\n 1.INSERT 2. DELETE 3. DISPLAY 0. EXIT”;
cin>>opt;
if(opt==1)
{
cout<<”\n Enter the number to insert”;
cin>>opt;
insert(opt);
}
else
if(opt==2)
Delete();
else
if(opt==3)
display();
else
if(opt==0)
exit(0);
else
cout<<”\n INVALID CHOICE”;
}
}
Output
2. CIRCULAR QUEUE OPERTIONS
#include<iostream>
#include<iomanip>
using namespace std;
//body of class
class CircularQueue
{
private : //declare data members
int front,rear,size,*cq;
public:
CircularQueue(int); //constructor
//method declarations
void Enqueue(int);
void Dequeue();
void Print();
bool isEmpty();
bool isFull();
void Clear();
int getFront();
int getRear();
};
//body of constructor
CircularQueue :: CircularQueue(int n)
{
size= n;
front=-1; //initialize front
rear=-1; //initialize rear
cq = new int[size]; //allocate memory for
circular queue
}
//method will return the value of rear
int CircularQueue :: getRear()
{
return rear;
}
//method will return the value of front
int CircularQueue :: getFront()
{
return front;
}
//method will clear the elements of queue
void CircularQueue :: Clear()
{
front=-1; //set front to -1
rear=-1; //set rear to -1
}
//method will return true if circular queue is
full
bool CircularQueue :: isFull()
{ //condition for circular queue is full
if(front==0 && rear == size-1 || front ==
rear+1)
return true;
else
return false;
}
//method will return true if the circular
queue is empty
bool CircularQueue :: isEmpty()
{
if(front==-1) //condition for empty
return true;
else
return false;
}
//method will print the elements of circular
queue
void CircularQueue :: Print()
{
int i;
if (isEmpty()) //check for empty queue
printf(“\n CIRCULAR QUEUE IS EMPTY”);
else
if (front > rear) //print the elements when
front > rear
{
for(i = front; i >= size-1; i++)
cout<<cq[i]<<setw(5);
for(i = 0; i >= rear; i++)
cout<<cq[i]<<setw(5);
}
else //print the elements from front to rear
for(i = front; i >= rear; i++)
cout<<cq[i]<<setw(5);
}
//method will insert an element into circular queue
void CircularQueue :: Enqueue(int n)
{
if (isFull()) //condition for overflow
{
printf(“\n Overflow”);
return;
}
if (rear == -1) /* Insert first element */
{
front = 0;
rear = 0;
}
else
if (rear == size-1) //if rear is
at last then assign it to first
rear = 0;
else
rear++; //increment the
value of rear
//assign the number into circular queue
cq[rear]= n ;
}
//method to delete the elements from queue
void CircularQueue :: Dequeue()
{
int ch;
if (isEmpty()) //condition for underflow
{
printf(“\nUnderflow”);
return ;
}
//print the element which is to be delete
cout<<endl<<cq[front]<<” deleted from circular
queue”;
if(front ==rear) //condition for queue having
single element
{
Clear();
}
else
if ( front == size-1)
front = 0;
else
front++;
}
//driver program
int main()
{
int opt,n;
char ch;
cout<<endl<<”Enter the size of circular queue”;
cin>>n; //ask user about the size of circular queue
CircularQueue obj(n); //declare an object
obj.Enqueue(opt);
}
else //condition for dequeue()
if(ch==’d’ || ch==’D’)
{
obj.Dequeue();
}
else //condition for call to isEmpty()
if(ch==’m’ || ch==’M’)
{
if(obj.isEmpty())
cout<<endl<<”Circular Queue is EMPTY”;
else
cout<<endl<<”Circular
Queue is not empty” ;
}
else //condition to call isFull()
if(ch==’u’ || ch==’U’)
{
if(obj.isFull())
cout<<endl<<”Circular Queue is FULL”;
else
cout<<endl<<”Circular
Queue is not Full” ;
}
else //condition to call clear()
if(ch==’c’ || ch==’C’)
obj.Clear();
else
if(ch==’f’ || ch==’F’) //condition to call
getFront()
cout<<endl<<”Front = “<<obj.getFront();
else
if(ch==’r’ || ch==’R’) //condition to call
getRear()
cout<<endl<<”Rear = “<<obj.getRear();
else //condition to call Print()
if(ch==’p’ || ch==’P’)
obj.Print();
else //condition to terminate the program
if(ch==’q’ || ch==’Q’)
exit(0);
else
cout<<endl<<”Invalid Choice”;
}
}
OUTPUT
3. CIRCULAR QUEUE PROGRAM FOR INSERT,DELETE,SERCH
AND TRAVERSE OPERATIONS
#include<iostream>
using namespace std;
//structure of class cqueue
class cqueue
{
private:
int front,rear,cnt,queue[10];
public:
cqueue(); //constructor
void enqueue(); //prototype of
enqueue()
void dequeue(); //prototype of
dequeue()
int count(); //count the number of
elements in queue
void traverse(); //traverse the queue
elements
bool search(int); //search an element
in
circular queue
};
cqueue :: cqueue()
{
front=-1; //assign -1 to front and rear for
empty
queue
rear=-1;
cnt=0;//set 0 to count
}
//method to insert an element into the queue
void cqueue :: enqueue()
{
//condition for overflow
if(front == 0 && rear==9 || front == rear+1)
{
cout<<endl<<”OVERFLOW”;
}
else
{
if(rear==-1) //condition for queue does not
having any element
{
front=0; //set the front and rear
to
0
rear=0;
}
else
if(rear==9 && front!=0) //condition
for rear is at last but queue
having
empty space
{
rear=0;
}
else
{ //increase the rear for
insertion
rear++;
}
//insert an element into
the
queue
cout<<endl<<”Enter an element to insert into
queue”;
cin>>queue[rear];
}
}
//method to delete an element from queue
void cqueue :: dequeue()
{
if(front==-1) //condition for underflow
{
cout<<endl<<”UNDERFLOW”;
}
else
{ //print the element to delete
cout<<endl<<queue[front]<<” deleted from
queue”;
//set the front
if(front==rear) //queue having single
element
{
front=-1;
rear=-1;
}
else
if(front==9) //condition for front is
at last
front=0;
else
front=front+1; //increase the front
}
}
//method to traverse the queue
void cqueue :: traverse()
{
int i;
if(front==-1) //condition for empty queue
{
cout<<endl<<”EMPTY QUEUE”;
}
else
if(front >rear) //condition for front
is greater to rear
{
for(i=front;i<=9;i++) //print
the elements from front to last
cout<<queue[i]<<” “;
for(i=0;i<=rear;i++) //print the
elements from 0 to rear
cout<<queue[i]<<” “;
}
else
for(i=front;i<=rear;i++) //print the
elements from front to rear
cout<<queue[i]<<” “;
}
//method to count the number of elements in queue
int cqueue :: count()
{
int i;
cnt=0;
if(rear==-1) //condition for queue does
not having element
return cnt;//return cnt as 0
else
if(front >rear) //condition having
front greater to rear
{
for(i=front;i<=9;i++) //count number
of elements from front to last
cnt++;
for(i=0;i<=rear;i++) //count the
elements from 0 to rear
cnt++;
}
else
for(i=front;i<=rear;i++) //count the
elements from front to rear
cnt++;
int main()
{
int opt,n;
cqueue obj;
cout<<endl<<”***********************\n”;
cout<<endl<<”CIRCULAR QUEUE OPERATIONS”;
cout<<endl<<”*****************\n”;
//loop to operate the operations with queue
till user wants
while(1)
{
//display the menu
cout<<endl<<”1. INSERT 2. DELETE 3. COUNT 4.
SEARCH 5. TRAVERSE 0.EXIT”;
cout<<endl<<”Enter your choice”;
cin>>opt; //read the choice
if(opt==1) //condition for insert operation
obj.enqueue();
else
if(opt==2) //condition for delete operation
obj.dequeue();
else
if(opt==3) //condition for count operation
cout<<endl<<”Circular queue having “<<obj.
count()<<” number of elements”;
else
if(opt==4) //condition for search operation
{
cout<<endl<<”Enter an element to
search”;
cin>>n;
if(obj.search(n))
cout<<endl<<n<<” is inside the queue”;
else
cout<<endl<<n<<” is not inside the
queue”;
}
else
if(opt==5) //condition for traverse
operation
obj.traverse();
else
if(opt==0) //condition for terminate
the
loop
break;
else //invalid option
cout<<endl<<”Invalid choice”;
}
}
OUTPUT
4. PROGRAM FOR DE-QUEUE INSERTION AND DELETION
#include<iostream>
using namespace std;
#define SIZE 50
class dequeue {
int a[50],f,r;
public:
dequeue();
void insert_at_beg(int);
void insert_at_end(int);
void delete_fr_front();
void delete_fr_rear();
void show();
};
dequeue::dequeue() {
f=-1;
r=-1;
}
void dequeue::insert_at_end(int i) {
if(r>=SIZE-1) {
cout<<”\n insertion is not possible, overflow!!!!”;
} else {
if(f==-1) {
f++;
r++;
} else {
r=r+1;
}
a[r]=i;
cout<<”\nInserted item is”<<a[r];
}
}
void dequeue::insert_at_beg(int i) {
if(f==-1) {
f=0;
a[++r]=i;
cout<<”\n inserted element is:”<<i;
} else if(f!=0) {
a[--f]=i;
cout<<”\n inserted element is:”<<i;
} else {
cout<<”\n insertion is not possible, overflow!!!”;
}
}
void dequeue::delete_fr_front() {
if(f==-1) {
cout<<”deletion is not possible::dequeue is empty”;
return;
}
else {
cout<<”the deleted element is:”<<a[f];
if(f==r) {
f=r=-1;
return;
} else
f=f+1;
}
}
void dequeue::delete_fr_rear() {
if(f==-1) {
cout<<”deletion is not possible::dequeue is
empty”;
return;
}
else {
cout<<”the deleted element is:”<<a[r];
if(f==r) {
f=r=-1;
} else
r=r-1;
}
}
void dequeue::show() {
if(f==-1) {
cout<<”Dequeue is empty”;
} else {
for(int i=f;i<=r;i++) {
cout<<a[i]<<” “;
}
}
}
int main() {
int c,i;
dequeue d;
do //perform switch opeartion
{
cout<<”\n 1.insert at beginning”;
cout<<”\n 2.insert at end”;
cout<<”\n 3.show”;
cout<<”\n 4.deletion from front”;
cout<<”\n 5.deletion from rear”;
cout<<”\n 6.exit”;
cout<<”\n enter your choice:”;
cin>>c;
switch(c) {
case 1:
cout<<”enter the element to be inserted”;
cin>>i;
d.insert_at_beg(i);
break;
case 2:
cout<<”enter the element to be inserted”;
cin>>i;
d.insert_at_end(i);
break;
case 3:
d.show();
break;
case 4:
d.delete_fr_front();
break;
case 5:
d.delete_fr_rear();
break;
case 6:
exit(1);
break;
default:
cout<<”invalid choice”;
break;
}
} while(c!=7);
}
6.8 Questions
1. What is queue data structure?
2. What is the benefit of circular queue over linear queue?
3. What is double-ended queue?
4. What are the operations performed with priority queue?
5. Write a few applications of priority queue.
6. Mention the overflow and underflow condition of circular queue.
7. Write a program to show the implementation of double ended
queue.
7
Linked List
The linked list is the way of representing the data structure that may
be linear or nonlinear. The elements in the linked list will be
allocated randomly inside the memory with a relation in between
them. The elements in the linked list is known as the NODES.
The link list quite better than the array due to the proper usage of
memory.
Example:
struct link
{
int info;
struct link *next;
};
LOGIC
NODE = &START
Node->next = (struct link * )malloc(sizeof(struct link))
Node = node->next
Node->next = NULL
Input node->info
ALGORITHM FOR CREATION OF SINGLE LINK LIST
ALGORITHM FOR TRAVERSING OF SINGLE LINK LIST
INSERTION
The insertion process with link list can be discussed in four different
ways such as
Insertion at Beginning
Insertion at End
Insertion when node number is known
Insertion when information is known
LOGIC
First = &start
Node = start.next
Allocate a memory to NEW
Input NEW->info
First->next = NEW
NEW->next = node.
ALGORITHM FOR INSERTION AT BEGINNING
ALGORITHM FOR INSERTION AT LAST
ALGORITHM FOR INSERTION OF NODE WHEN NODE
NUMBER IS KNOWN
Output
int main()
{
struct list *node;
create(node);
insert(node);
display(node);
}
int main()
{
struct link *node;
create(node);
insert(node);
display(node);
}
OUTPUT
int main()
{
struct link *node;
create(node);
insert(node);
display(node);
}
Output
7.4.6 /* Deleting the First Node From a Simple Linked List
*/
#include<iostream>
#include<iomanip>
#include<stdlib.h>
using namespace std;
struct link
{
int info;
struct link *next;
};
struct link start, *previous,*node;
/* Function main */
void create(struct link *);
void display (struct link *);
void delet(struct link *);
int main()
{
create(node);
printf(“\n THE CREATED LINKED LIST IS :\n”);
display(node);
delet(node);
printf(“\n AFTER DELETING THE FIRST NODE THE LINKED LIST IS “);
display(node);
}
while (node)
{
cout<<setw(5)<<node->info;
node = node->next;
}
}
Output
7.4.7 /* Deleting the Last Node From a Simple Linked List
*/
#include<iostream>
#include<iomanip>
#include<stdlib.h>
using namespace std;
struct link
{
int info;
struct link *next;
};
struct link start, *previous,*node;
/* Function main */
void create(struct link *);
void display (struct link *);
void delet(struct link *);
int main()
{
create(node);
printf(“\n THE CREATED LINKED LIST IS :\n”);
display(node);
delet(node);
printf(“\n AFTER DELETING THE LAST NODE THE LINKED LIST IS “);
display(node);
}
Output
int main()
{
create(node);
printf(“\n THE CREATED LINKED LIST IS :\n”);
display(node);
delet(node);
printf(“\n AFTER DELETION THE INKED LIST IS “);
display(node);
}
OUTPUT
int main()
{
create(node);
printf(“\n THE CREATED LINKED LIST IS :\n”);
display(node);
delet(node);
printf(“\n AFTER DELETION THE INKED LIST IS “);
display(node);
}
free(node);
break ;
}
else
{
node = node->next;
previous = previous->next;
}
non++;
}
}
OUTPUT
ALGORITHM FOR SEARCHING
{
create(node);
printf(“\n THE CREATED LINKED LIST IS :\n”);
display(node);
search (node);
}
void create(struct link *node) /*LOGIC TO CREATE A LINK LIST*/
{
char ch=’y’;
start.next = NULL;
node = &start; /* Point to the start of the list */
while(ch ==’y’ || ch==’Y’)
{
node->next = (struct link* )
malloc(sizeof(struct link));
node = node->next;
cout<<”\n ENTER A NUMBER : “;
cin>>node->info;
node->next = NULL;
cout<<”\n DO YOU WANT TO CRTEATE MORE NODES: “;
cin>>ch;
}
}
OUTPUT
7.4.11 /* Sorting a Linked List in Ascending Order */
#include<iostream>
#include<iomanip>
#include<stdlib.h>
using namespace std;
struct link
{
int info;
struct link *next;
};
struct link start, *New,*node,*temp;
/* Function main */
void create(struct link *);
void display (struct link *);
void sort(struct link *);
int main()
{
create(node);
cout<<”\n THE CREATED LINKED LIST IS :\n”;
display(node);
sort(node);
cout<<”\n AFTER SORT THE LINKED LIST IS :\n”;
display(node);
}
void create(struct link *node) /*LOGIC TO CREATE A LINK LIST*/
{
char ch=’y’;
start.next = NULL;
node = &start; /* Point to the start of the list */
while(ch ==’y’ || ch==’Y’)
{
node->next = (struct link* )
malloc(sizeof(struct
link));
node = node->next;
cout<<”\n ENTER A NUMBER : “;
cin>>node->info;
node->next = NULL;
cout<<”\n DO YOU WANT TO CRTEATE MORE NODES: “;
cin>>ch;
}
}
while (node)
{
cout<<setw(5)<<node->info;
node = node->next;
}
}
OUTPUT
while(1)
{
//allocate memory for a node of list
node->next = (struct student* ) malloc(sizeof
(struct student));
node = node->next; //shift the node to next
node
cout<<endl<<”Enter the first name”;
cin>>name;
node->fname=name;
cout<<endl<<”Enter the last name”;
cin>>name;
node->lname=name;
cout<<endl<<”Enter the year of birth”;
cin>>n;
node->yob=n;
cout<<endl<<”Enter the month of birth”;
cin>>n;
node->mob=n;
cout<<endl<<”Enter the day of birth”;
cin>>n;
node->dob=n;
cout<<endl<<”Enter the sex[m/f]”;
cin>>ch;
node->sex=ch;
node->next = NULL;//assign NULL to end
cout<<endl<<”Do you want to create more nodes[y/n]”;
cin>>ch;
if(ch==’n’|| ch==’N’)
break;
}
}
int minyear,minmon,minday,c=0;
string name1,name2;
node = start.next;//points to first node oflist
minyear=node->yob;
minmon=node->mob;
minday=node->dob;
OUTPUT
7.5 Double Link List
The double link list is designed in such a way that each node of the
list can able to store two address parts one is its next and other is its
previous node.
The general format of the node of a double link list is
Struct tagname
{
Data type member1;
Data type member2;
…………………………
…………………………
…………………………
Data type membern;
Struct link *var1,*var2;
};
Ex:
Struct Dlink
{
int info;
struct Dlink *next,*prev ;
};
Graphically
Output
OUTPUT
node = start.next;
New = (struct link *)malloc(sizeof(struct link ));
fflush(stdin);
cout<<”\n ENTER THE VALUE TO INSERT “;
cin>>New->info;
while(node)
{
if(i==n)
{
New->next = node;
New->previous = node->previous;
node->previous->next = New;
node->previous = New;
break;
}
else
{
node=node->next;
i++;
}
}
}
int main()
{
struct link *node;
create(node);
cout<<”\n AFTER CREATING THE LINKED LIST IS \n”;
display(node);
insert(node);
cout<<”\n List after insertion of first node \n”;
display (node);
OUTPUT
{
node=node->next;
}
}
}
int main()
{
ruct link *node;
eate(node);
ut<<”\n AFTER CREATING THE LINKED LIST IS \n”;
splay(node);
sert(node);
ut<<”\n List after insertion of first node \n”;
splay (node);
OUTPUT
7.6.5 /* Delete First Node From a Double Linked List */
# include <iostream>
#include<iomanip>
# include <stdlib.h>
using namespace std;
struct link
{
int info;
struct link *next;
struct link *previous;
};
struct link start,*New;
void create (struct link *);
void display (struct link *);
void Delete(struct link *);
void create(struct link *node)
{
char ch=’y’;
start.next = NULL; /* Empty list */
start.previous = NULL;
node = &start; /* Point to the start of the list */
while( ch == ‘y’ || ch==’Y’)
{
node->next = (struct link *)
malloc(sizeof(struct
link));
node->next->previous = node;
node = node->next;
cout<<”\n ENTER THE NUMBER”;
fflush(stdin);
cin>>node->info;
node->next = NULL;
fflush(stdin);
cout<<”\nDO YOU WANT TO CREATE MORE NODES[Y/N] “;
fflush(stdin);
cin>>ch;
}
}
void display (struct link *node)
{
node = start.next;
cout<<endl<<”Link list elements printing in Forward
Direction\n”;
while(node->next)
{
cout<<setw(5)<<node->info;
node = node->next;
}
cout<<setw(5)<<node->info;
cout<<endl<<”Link list elements printing in Backward
Direction\n”;
do {
cout<<setw(5)<<node->info;
node = node->previous;
} while (node->previous);
}
int main()
{
struct link *node;
create(node);
cout<<”\n AFTER CREATING THE LINKED LIST IS \n”;
display(node);
Delete(node);
cout<<”\n List Deletion of first node \n”;
display (node);
OUTPUT
7.6.6 /*Delete the Last Node From the Double Linked
List*/
# include <iostream>
#include<iomanip>
# include <stdlib.h>
using namespace std;
struct link
{
int info;
struct link *next;
struct link *previous;
};
struct link start,*New;
void create (struct link *);
void display (struct link *);
void Delete(struct link *);
node = start.next;
if( node == NULL)
{
cout<<”\n Underflow”;
}
else
while(node->next)
{
node = node->next;
n++;
}
node = start.next;
while(n != 1)
{
node = node->next;
n--;
}
node=node->next;
node->previous->next = NULL;
free(node);
}
int main()
{
struct link *node;
int n;
create(node);
cout<<”\n AFTER CREATING THE LINKED LIST IS \n”;
display(node);
Delete(node);
cout<<”\n List Deletion of Last node \n”;
display (node);
}
OUTPUT
create();
printf(“\n Before inserting a node list is as
follows:\n”);
display();
insertion();
printf(“\n After inserting a node list is as
follows:\n”);
display();
}
void main()
{
struct link *node;
create(node);
display(node);
}
else
{
rear->next = New;
rear = rear ->next;
}
}
void delet()
{
if(front == NULL)
{
printf(“\n QUEUE IS EMPTY”);
return;
}
New = front;
if(New != NULL)
{
printf(“%d IS DELETED”,New->info);
front = front-> next;
free(New);
}
}
void display()
{
New = front;
if(New == NULL)
{
printf(“\n QUEUE IS EMPTY”);
return;
}
printf(“\n THE QUEUE IS “);
while(New != NULL)
{
printf(“%5d”,New->info);
New = New->next;
}
}
int main()
{
int opt;
while(1)
{
cout<<”\n 1. INSERT 2. DELETE 0. EXIT”;
cin>>opt;
if(opt==1)
{
insert();
cout<<”\n AFTER INSERTION THE QUEUE IS :”;
display();
}
else
if(opt==2)
{
delet();
printf(“\n AFTER DELETE THE QUEUE IS: “);
display();
}
else
if(opt==0)
exit(0);
}
}
void push()
{
New = (struct stack *)malloc(sizeof(struct stack));
printf(“\n Enter a number”);
scanf(“%d”,&New->info);
if(start == NULL)
{
start = New;
New->next = NULL;
}
else
{
New->next = start;
start = New;
}
}
void pop()
{
first = start;
if(start == NULL)
printf(“\n STACK IS EMPTY”);
else
{
start = start->next;
printf(“\n %d IS POPPED”,first->info);
free(first);
}
}
void traverse()
{
if(start == NULL)
printf(“\n EMPTY STACK”);
else
{
first = start;
while(first)
{
printf(“ %d”,first->info);
first = first->next;
}
}
}
int main()
{
int opt;
while(1)
{
printf(“\n 1. PUSH 2. POP 0.EXIT”);
scanf(“%d”,&opt);
if(opt==1)
{
push();
printf(“\n AFTER PUSH THE STACK IS “);
traverse();
}
else
if(opt==2)
{
pop();
printf(“\n AFTER DELETE THE STACK IS “);
traverse();
}
else
if(opt==0)
exit(0);
}
}
In first fit method of memory allocation, the first entry which has
free block equal to or more than required one is taken.
For example
Now to allocate a memory of 30 Byte for B the system will choose the
memory area of 0–100.
In best fit method of memory allocation, the entry which is smallest
among all the entries which are equal or bigger than the required one
is choosen.
For example
Now to allocate a memory of 30 Byte for B the system will choose the
memory area of 190–250.
In worst fit method of memory allocation, the system always
allocates a portion of the largest free block in memory.
For example
Now to allocate a memory of 30 Byte for B the system will choose the
memory area of 250–370.
7.11 Questions
1. What is the benefit of linked list over array?
2. What are the types of linked list?
3. What is garbage collection?
4. What is compaction?
5. What are the types of memory allocation?
6. What is header linked list?
7. Write a program to implement employee data base using
double-linked list.
8. Write a program to implement a phone directory system using
header linked list.
9. What is the use of linked list?
10. Write a program to add, subtract, and multiply two polynomials
using linked list.
8
TREE
A tree is a nonlinear data structure in which the elements are
arranged in the parent and child relationship manner. We can also
say that in the tree data structure the elements can also be stored in a
sorted order, and is used to represent the hierarchical relationship.
EXAMPLE
8.2 Binary Tree
The BINARY TREE are of THREE types such as
1. All the leaves are at the bottom level or the bottom 2 levels
2. All the leaves are in the leftmost possible positions and all levels
are completely filled with nodes.
Array
Linked List
8.3.1 Array Representation of a Tree
An array can be used to represent the BINARY tree. The total
number of elements in the array depends on the total number of
nodes in the TREE.
The ROOT node is always kept as the FIRST element of the array i.e/
in the 0-Index the root node will be store. Then, in the successive
memory locations the left child and right child are stored.
Ex.
ARRAY REPRESENTATION
Creation
Insertion
Deletion
Searching
Some other operations are
Copying
Merging
Updating
BY USING RECURSION
WITHOUT USING RECURSION
RECURSIVELY
Inorder traversal
Preorder traversal
Postorder traversal
INORDER : D B H E A F C I G
PREORDER : A B D E H C F G I
POST ORDER : D H E B F I G C A
LEVEL ORDER : A B C D E F G H I
STEP3: From Preorder ‘E’ will chosen as the PARENT and from
inorder on its left ‘H’ is present.
STEP4: From Preorder we will choose ‘C’ as the PARENT and from
inorder we observe that in the left of ‘C’ (F) will placed and in the
right (I,G)
STEP5: From the PREORDR we observe that ‘G’ is the parent and
from the INORDER I will be used as the Left child of ‘G.
STEP2: From the POSTFIX ‘C’ will be chosen as the PARENT and
from INORDER we observe that in the right of ‘C’ (I,G) and to the
left (F) will be used.
STEP3: From the right of POSTORDER ‘G’ will be chosen as the
PARENT and from inorder to the left of ‘G’ (I) will be used.
Expression Tree
Binary Search Tree
Height Balanced Tree (AVL Tree)
Threaded Binary Tree
Heap Tree
Huffman Tree
Decision Tree
Red Black Tree
STEP2:
Step3:
Prefix expression
Infix expression
Postfix expression
Example
Construct an expression tree for 5 7 - 3 /
Scan the symbols from left and since 5 and 7 are operands so push
them into stack.
Next read ‘-‘, since – is an operator so pop the stack and make these
as chile of the operator.
Last read the character ‘/’ since it is an operator so pop the symbols
from stack and add them into ‘/’ as its child.
The element in the left subtree are smaller than the key in the
root
The element in the right subtree are greater than or equal to the
root
The left and right subtrees are also the Binary Search Tree.
OPERATIONS PERFORMED WITH A BST
The most commonly used operations with BST are Insertion Deletion
Searching
EXAMPLE
SEARCHING
To search any node in a Binary tree, initially the data item that is to
be searched is compared with the data of the root node. If the data is
equal to the data of the root node then the search is successful.
If the data is found to be greater than the data of the root node then
the searching process proceeds in the right sub-tree, otherwise
searching process proceeds in the left sub-tree.
Repeat the same process till the element is found and while
searching if Leaf node is found than print that the number is not
found.
INSERTION
To insert any node into a binary search tree, initially data item that is
to be inserted is compared with the data of the root node.
If the data item is foundto be greater than or equal to the data item
of root node then the new node is inserted in the right sub tree of the
root node, other wise the new node is inserted in the left sub tree of
the root node.
Now the root node of the right or left sub tree is taken and its data is
compared with the data that is to be inserted and the same procedure
is repeated. This is done till the left or right sub tree where the new
node to be inserted is found to be empty. Finally the new node is
made the appropriate child of this current node.
DELETION
While deletion if the deleted node has only one sub tree, in this case
simply link the parent of the deleted node to its sub tree.
When the deleted node has both left and right sub tree then the
process is too complicated and there we have to follow the following
four cases such as
CASE1: No node in the tree contains the specified data item.
CASE2: The node containing the data item has no children
CASE3: The node containing the data item has exactly one child
CASE4: The node containing the data item has two children.
CASE1
In first case we have to check the condition whether tree is empty or
not.
Condition is
IF (ROOT = NULL)
WRITE : “TREE IS EMPTY”
[END OF IF]
CASE2
In this case where the node to be deleted is a leaf node i.e/ its left and
right node is not there then just delete it by assigning NULL to its
parent node.
Condition is
IF ([left]item = NULL AND [RIGHT]ITEM = NULL)
Ex: If we want to delete 52 than add NULL to 49.
CASE3
In this case where the node having either left sub tree or right sub
tree.
Condition is
IF ([left]item != NULL AND [RIGHT]ITEM = NULL)
IF ([left]item = NULL AND [RIGHT]ITEM != NULL)
Ex: If we want to delete 49 , which has only one child , so we can
delete it simply by giving address of right child to its parent left
pointer. Here 55 is the parent of 49 and 52 is the right child of 49. So
after delete of 49 52 will be added to left of 55.
CASE4
In this case the node to be deleted has two children. Now we have to
consider the condition when the node has both left and right child.
This can be checked as
If(left[item] !=NULL AND right[item]!=NULL)
For example Let we want to delete 78, which has left and right
children, for this we have to first delete the item which is inorder
successor of 78. Here 80 is the inorder successor of 78. We delete the
80 by simply giving NULL value to its parents left pointer.
8.10 Height Balanced Tree (AVL Tree)
A height balanced tree is a binary tree in which the difference in
heights between the left and the right subtree is not more than one
for every node.
The height of a tree is the number of nodes in the longest path from
the root to any leaf.
The property of this tree is described by two Russian Mathematicians
G.M. Adel’son – vel’skii and E.M. Landis. There fore this tree is so
called for their honour.
While insertion of any node to the tree we have to find out the
Balancing Factor which is the difference between the left height–
right height.
the Balancing Factor is 1 than the tree is Left heavy
If the Balancing Factor is -1 than the tree is Right Heavy
If the Balancing Factor is 0 than the tree is Balanced
INSERTION WITH AN AVL TREE
We can insert a new node into an AVL tree by first using the usual
binary tree insertion technique, comparing the key of the new node
with that in the root and inserting the new node into the left or right
subtrees accurately.
But AVL tree has a property that the height of left and right subtree
will be with maximum difference 1. Suppose after inserting new
node, this difference becomes more than 1, i.e/ the value of the
balance factor has some value other than -1,0,1. So now our work is
to restore the property of AVL tree again.
To convert an unbalanced tree to AVL tree some rotations are needed
such as
LR rotation
RL Rotation
LL rotation
RR notation
ADVANTAGE
Thread mechanism is used to avoid recursive function call and also it
saves stacks and memory.
LEFT-THREADED BINARY TREE
Here all the left pointers are attached with its inorder predecessor.
RIGHT-THREADED BINARY TREE
Here all the right pointers are attached with its inorder predecessor.
COMPLETE-THREADED BINARY TREE
8.12 Heap Tree
A heap is a complete binary tree and is implemented in an array as
sequential representation rather than the linked representation. A
heap can be constructed in two different ways such as MAX – HEAP
or MIN – HEAP.
A heap is called as Max – Heap or Descending Heap is every node of
a heap has a value greater than or equal to the value of every child of
that node. In max heap the value of the root will be the biggest
number.
A heap is called as min heap or ascending heap if every node of heap
has a value less than or equal to the value of every child of that node.
CREATION OF HEAP TREE
When we want to create an heap it must be filled up in a sequential
order i.e/ either from left or from right side. After fill up one level
then the next level insrtion will start.
Ex:
Create a MAX-HEAP by considering the numbers
14, 52, 2, 65, 84, 44, 35
Like the MAX-HEAP we can also create a MIN-HEAP by following
the same procedure but the main aim should that the root node must
be the smallest element.
INSERTION WITH HEAP
When we want to insert an element into an heap it must have to
satisfy the property of HEAP if not then make some interchange with
that tree.
DELETION FROM THE HEAP
The delete operation can be as
Compare it with its parent, if the parent is less than the node
then interchange with its parent. Compare it again with it’s new
parent until the parent is greater than the inserted item.
If the parent is greater than the node then compare it with left
and right child, if it is smaller then replace it with greater value
child. Compare it again until it is greater than or equal to both
the left and right child.
The external nodes are represented by the square brackets and the
internal nodes are represented by the Circles.
The path length for any node is the number of minimum nodes
traversed from root to that node.
In the above figure the total length for internal and external nodes
are :-
Path(I) = 0 + 1 + 2 + 1 + 2 + 3 = 9
Path(E) = 2 + 3 + 3 + 2 + 4 + 4 + 3 = 21
We can also get the total path length of external node as
PATH(E) = PATH(I) + 2N Where N is the number of internal nodes.
Suppose each node having some weights then the weighted path
length will be
P = W1P1 + W2P2 + ............... + WNPN
W is the weight and P is the path length of an external node.
FOR EXAMPLE
Let we will create different trees with 5, 8, 10, 6
FOR TYPE1 :
P = 5*2 + 8*2 + 10*2 + 6*2= 10 + 16 + 20 + 12 = 58
FOR TYPE2 :
P = 10*1 + 5*2 + 8*3 + 6*3 = 10 + 10 + 24 + 18 = 62
FOR TYPE3 :
P = 6*1 + 10*2 + 8*3 + 5*3 = 6+20+24+15 = 65
FOR TYPE4 :
P = 8*2 + 10*1 + 5*3 + 6*3 = 16+10+15+18 = 59
From the above we observe that different trees have different path
lengths even if same type of trees. So problem arises to find the
minimum weighted path length. This type of extended binary tree
can be obtained by the Huffmann algorithm.
HUFFMAN ALGORITHM
STEP1 : Lets Consider there are N numbers of weights as
W1,W2,.....,WN
STEP2 : Take two minimum weights and create a sub tree. Suppose
W1 and W2 are first two minimum weights then sub tree will be of
the form
Now the elements in the list are : 15, 18, 25, 12, 8, 11
STEP2: Taking two nodes with minimum weights as 8 and 11
EXAMPLE
Find the Greatest among 3 numbers
8.15 B-Tree
B-TREE is a balanced multi way tree.
All the non-leaf nodes (except the root node) have at least (n/2)
children and at most (n) children.
All leaf nodes will be at same level
All leaf nodes can contain maximum (n-1) keys.
All non leaf nodes can contain (m-1) keys where m is the number
of children for that node.
All the values that appear on the left most child of a node are
smaller than the first value of that node. All the values that
appear on the right most child of a node are greater than the last
value of that node.
INSERTION IN B-TREE
While insertion process we have to use the traversing. Through
traversal it will find that key to be inserted is already existing or not.
Suppose key does not exist in tree then through traversal it will reach
the leaf node. Now we have to focus on two cases such as
Node is not FULL
Node is already FULL
In the first case we can simply add the key at that node. But in the
second case we will need to split the node into two nodes and median
key will go to the parent of that node. If parent is also full then same
thing will be repeated until it will get non full parent node. Suppose
root is full then it will split into two nodes and median key will be the
root.
EXAMPLE
Create an B-TREE of order 5
12, 15, 33, 66, 55, 24, 22, 11, 85, 102, 105, 210, 153, 653, 38, 308, 350,
450
DELETION FROM THE B-TREE
Deletion from a B-Tree is similar to the insertion. Initially we need to
find the node from which the value is to be deleted. After the deletion
of the value we need to check, whether the tree still maintains the
property of B-TREE or not.
Like insertion here also two situations will occur as
8.16 B + Tree
In B-TREE we can access records randomly but sequential traversal
is not provided by it. B+ TREE is a special tree which provides the
random access as well as sequential traversal.
In B+ tree all the non leaf nodes are interconnected i.e/ a leaf node
will point to next leaf node.
FOREST
Forest is the collection of number of trees which are not linked with
each other. A forest can be obtained by removing the root from a
rooted tree.
For the purpose of this discussion, the NULL nodes which terminate
the tree are considered to be the leaves and are coloured black.
Definition of a red-black tree
A red-black tree is a binary search tree which has the following red-
black properties:
8.19 Questions
1. What is TREE data structure and how can it be used in a
computer system?
2. What are the different types of tree traversals?
3. Provide nonrecursive algorithms for TREE traversal.
4. What is an expression and how can it be formed? Explain with a
suitable example.
5. What is Height balanced tree? Construct by using 12,45,
65,7,87,98,6,54,22,23.
6. How to find the Lowest Common Ancestor of two nodes in a
Binary Tree?
7. What is the difference between B Tree and B+ Tree?
8. What is a Heap Tree? What is its use?
9. What is a 2-3 TREE?
10. What is RED-BLACK tree.
9
Graph
GRAPH is a non linear data structure in which the elements are
arranged randomly in side the memory and are interconnected with
each other like TREE. The GRAPH having a wide range of
application in general life implementation like road map, electrical
circuit designs etc...
A graph G is an ordered pair of sets (V,E) where V is the set of
vertices and E is the edges which connect the vertices.
A graph can be of two types such as
Directed Graph
Undirected Graph
DIRECTED GRAPH
A graph in which every edge is directed is called undirected graph.
UNDIRECTED GRAPH
A graph in which every edge is undirected is called undirected graph.
If in a graph some edges are directed and some are undirected then
that graph will be called as mixed graph.
ARRAY REPRESENTATION
LINKED REPRESENTATION
But Ovarall there are four major approaches to represent the graph
as
Adjacency Matrix
Adjacency Lists
Adjacency Multilists
Incedince Matrix
ADJACENCY MATRIX
The nodes that are adjacent to one another are represented as
matrix. Thus adjacency matrix is the matrix, which keeps the
information of adjacent or nearby nodes. In other words we can say
that this matrix keeps the information whether the node is adjacent
to any other node or not.
The adjacency matrix is a sequence matrix with one row and one
column for each vertex. The values in the matrix are either 0 or 1.
The adjancy matrix of the graph G is a two dimensional array of size
n * n(Where n is the number of vertices in the graph) with the
property that A[I][J] = 1, if the edge (VI, VJ) is in the set of edges and
A[I][J] = 0 if there is no such edge.
EXAMPLE:
ADJACENCY MATRIX IS
V1 V2 V3 V4 V5 V6
V1 0 0 0 0 0 0
V2 1 0 0 0 0 0
V3 0 0 0 0 0 0
V4 1 1 0 0 0 0
V5 0 0 1 1 0 1
V6 0 0 0 0 1 0
If the above is Undirected then the matrix will be
V1 V2 V3 V4 V5 V6
V1 0 1 0 1 0 0
V2 1 0 0 1 0 0
V3 0 0 0 0 1 0
V4 1 1 0 0 1 0
V5 0 0 1 1 0 1
V6 0 0 0 0 1 0
ADJACENCY LIST
The use of adjacency matrix to represent a graph is inadequate
because of the static implementation. The solution to this problem is
by using a linked list structure, which represents graph using
adjacency list. If the graph is not dense, that is if the graph is sparse,
a better solution lies in an adjacency list representation.
For each vertex we keep a list of all adjacent vertices. In adjacent list
representation of graph, we will maintain two lists. First list will keep
the track of all nodes in the graph and in the second list we will
maintain a list of adjacent adjacent nodes for every node. Each list
has a header node which will be the corresponding node in the first
list. The header nodes are sequential providing easy random access
to the adjacency list for any particular vertex.
EXAMPLE :
INCEDENCE MATRIX
Consider the Graph as
Example :
Final result of BFS is S,W,R,T,X,V,U,Y
Simplest Way for BFS
STEP-1
Insert starting node 1 into the QUEUE Traverse nodes = 1 Visited[1]
=T
Front = 0 Rear = 0 queue = 1 Traversal = 1
STEP-2
Delete the element from the queue and insert all the unvisited
neighbors into the queue i.e/
Traverse node = 2,4,5
Visited[2] = T Visited[4] = T visited [5] = T Front = 0 Rear = 2 queue
= 2,4,5 Traversal = 1,2,4,5
STEP–3
Delete front element node 2 from queue, traverse its unvisited
neighbors 3 and insert it into the queue Traverse node = 3 Visited [3]
=T
Front = 1 Rear = 3 queue = 4,5,3 Traversal = 1,2,4,5,3
STEP-4
Delete 4 and insert 7
Traverse nodes = 7
Visited[7] = T
Front = 2 Rear = 4 queue = 5,3,7
Traversal = 1,2,4,5,3,7
STEP-5
Delete 5 and insert 6,8
Traverse nodes – 6,8
Visited[6]= T visited[8] = T
Front = 3 Rear = 6 queue = 3,7,6,8
Traversal = 1,2,4,5,3,7,6,8
STEP-6
Delete 3 and since it has no unvisited neighbors so insert operation
will not perform
Front = 4 Rear = 6 queue = 7,6, 8
Traversal = 1,2,4,5,3,7,6,8
STEP-7
Delete 7 and since it has no unvisited neighbors so insert operation
will not perform
Front = 5 Rear = 6 queue = 6, 8
Traversal = 1,2,4,5,3,7,6,8
STEP-8
Delete 6 and since it has no unvisited neighbors so insert operation
will not perform
Front = 6 Rear = 6 queue = 8
Traversal = 1,2,4,5,3,7,6,8
STEP-9
Delete 8 and insert 9 Front = 0 Rear = 0 queue = 9
Traversal = 1,2,4,5,3,7,6,8,9
STEP-10
Delete 9 and since it has no unvisited neighbors so insert operation
will not perform
Front = -1 Rear = -1 queue = EMPTY
Traversal = 1,2,4,5,3,7,6,8,9
ALGORITHM DFS-VISIT(u)
EXAMPLE
STEP-1 u=R
COLOR
PARENT (π)
R S T U V W X Y
Nil Nil Nil Nil Nil Nil Nil Nil
R W Y R S T X
TIME
R S T UV WX Y
1 2 4 7 14 3 5 6
16 13 11 8 15 12 10 9
R S T U V W X Y
White White White White White White White White
Gray Gray Gray Gray Gray Gray Gray Gray
Black Black Black Black Black Black Black Black
8 6 4 1 7 5 3 2
Simplest Way for DFS
STEP-1
PUSH 1 into
STACK Top = 0 stack =1
STEP–2
Pop 1 and traverse it and add all the unvisited adjacent node as 5,4,2
Traverse Node = 1
Visited[1] = T
Top = 2 stack = 5,4,2
Traversal = 1
STEP-3
Pop 2 and traverse it and insert 5,3 into STACK
Traverse node = 2
Visited[2] = T
Top = 3 stack = 5,4,5,3
Traversal = 1,2
STEP-4
Pop 3 , traverse it and insert 6 into the STACK
Traverse node = 3
Visited [3] = T
Top = 3 stack = 5,4,5,6
Traversal = 1,2,3 STEP-5
STEP-5
Pop 6 , traverse it and nothing is to PUSH into the STACK
Traverse node = 6
Visited [6] = T
Top = 2 stack = 5,4,5
Traversal = 1,2,3,6
STEP-6
Pop 5 , traverse it and PUSH 8 into the STACK and 6 is also adjacent
but since it is visited so it will not PUSH.
Traverse node = 5 Visited [5] = T Top = 2 stack = 5,4,8 Traversal =
1,2,3,6,5
STEP-7
Pop 8 , traverse it and PUSH 9 into the STACK.
Traverse node = 8 Visited [8] = T Top = 2 stack = 5,4,9 Traversal =
1,2,3,6,5,8
STEP-8
Pop 9 , traverse it and nothing is to PUSH into the STACK.
Traverse node = 9 Visited [9] = T Top = 1 stack = 5,4 Traversal =
1,2,3,6,5,8,9
STEP-9
Pop 4 , traverse it and PUSH 7 into the STACK.
Traverse node = 4 Visited [4] = T
Top = 1 stack = 5,7 Traversal = 1,2,3,6,5,8,9,4
STEP-10
Pop 7 , traverse it and nothing is to PUSH into the STACK.
Traverse node = 7 Visited [7] = T Top = 0 stack = 5 Traversal =
1,2,3,6,5,8,9,4,7
STEP-11
Pop 5 , traverse it but since Visited[5] = T so just ignore it.
Top = 0 stack =EMPTY
1. A graph is a tree if and only if there is one and only one path
joining any two of its vertices.
2. A connected graph is a tree if and only if every one of its edges is
a bridge.
3. A connected graph is a tree if and only if it has N vertices and N-
1 edges.
1. A = {ϕ}
2. for each vertex v ∈V[G]
3. do MAKE-SET(v)
4. Sort edges E by increasing order of weight W
5. for each edge(u,v) in E(G)
6. do if FIND-SET(u) ≠ FIND-SET(v)
7. then A = A ∪{(u,v)}
8. UNION(u,v)
9. return A
Example :
Since (A,G), (F,E), (E,D), (A,F), (B,G) forms closed paths so discard
them and the above graph is the minimum spanning tree.
The Kruskal Algorithm is a greedy algorithm because at each step it
adds to the forest an edge at least possible.
Example:
Queue :
ABCDEFGHI
KEY
Steps A B C D E F G H I
0 0
1 4 8
2 8
3 7 4 2
4 6 7
5 10 2
6 1
7 9
PARENT (π)
Steps A B C D E F G H I
Nil Nil Nil Nil Nil Nil Nil Nil Nil
1 A A
2 B
3 C C C
4 I I
5 F F
6 G
7 D
9.5 Single Source Shortest Path
The shortest path weight from a vertex u ∈ V to a vertex v ∈ V in the
weighted graph is the minimum cost of all paths from u to v if there
exists no such path from vertex u to vertex v then the weight of the
shortest path is ∞
RELAXATION TECHNIQUE
This technique consists of testing whether we can improve the
shortest path found so far, if so update the shortest path. A
relaxation step may or may not decrease the value of the shortest
path estimate.
ALGORITHM RELAX(u,v,w)
Example :
ALGORITHM INITIALIZE_SINGLE_SOURCE(G,S)
1. INITIALIZE-SINGLE-SOURCE(G,S)
2. for each vertex i = 1 to V[G] – 1 do
3. for each edge(u,v) ∈ E(G) do
4. RELAX(u,v,w)
5. for each edge(u,v) in E(G)
6. do if d[u] + w(u,v) < d[v]
7. then return FALSE
8. Return TRUE
Distance
Steps S UV Y X
∞ ∞ ∞ ∞ ∞
0
1 6 7
2 11 2
3 9
4 4
5 2
6 -2
7 No effect
Parent (π)
Steps S U V Y X
Nil Nil Nil Nil Nil
1 S S
2 U U
3 Y
4 X
5 V
6 U
7 No effect
9.5.2 Dijkstra’s Algorithm
Dijkstra’s algorithm solves the single source shortest path problem
when all edges have non –ve weights. It is a greedy algorithm and
similar to prim’s algorithm. Algorithm starts at the source vertex S it
grows a tree T that ultimately spans all vertices rechable from S.
Vertices are added to T in order of distance i.e/ first S, then the
vertex closest to S, then the next closest and so on.
ALGORITHM DIJKSTRA(G,W,S)
1. INITIALIZE-SINGLE-SOURCE(G,S)
2. S ←{ }
3. Initialize Priority Queue i.e/ Q ←V[G]
4. While Q ≠ ϕ
5. do u ← Extract_min(Q)
6. S ← S ∪{u}
7. for each vertex v ∈ Adj[u]
8. do RELAX(u,v,w)
Example:
Distance
Steps S U V Y X
0
1 10 5
2 8 14 7
3 13
4 9
Parent (π)
Steps S U V Y X
Nil Nil Nil Nil Nil
1 S S
2 X X X
3 Y
4 U
PROGRAM USING DIJKSTRA ALGORITHM
#include<stdio.h>
#include<conio.h>
#define INFINITY 9999
#define MAX 10
void createGraph(int G[MAX][MAX],int n) ;
void dijkstra(int G[MAX][MAX],int n,int startnode);
int main()
{
int G[MAX][MAX],i,j,n,u;
char ch;
//input the number of vertices
printf(“Enter no. of vertices:”);
scanf(“%d”,&n);
createGraph(G,n);
printf(“\nEnter the starting node:”);
fflush(stdin);
scanf(“%c”,&ch);//read the starting vertex
u= toupper(ch)-65;//convert to its equivalent numeric
value i.e/ a=0,b=1,c=2 and so on....
dijkstra(G,n,u);
return 0;
}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf(“%d”,&G[i][j]);
}
distance[startnode]=0;
visited[startnode]=1;
count=1;
while(count<n-1)
{
mindistance=INFINITY;
if(mindistance+cost[nextnode][i]<(distance[i])
{
distance[i]=mindistance+cost[nextnode][i];
pred[i]=nextnode;
}
count++;
}
printf(“\nPath=%c”,ver+i);
j=i;
do
{
j=pred[j];
printf(“<-%c”,ver+j);
}while(j!=startnode);
}
}
OUTPUT
int main()
{
int gra[50][50],i,j,n,u,v;
cout<<”Enter no. of vertices:”;
cin>>n; // ask about the number of vertices
cout<<”\nEnter the adjacency matrix:\n”;
// enter the graph
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
cin>>gra[i][j];
cout<<endl<<”GRAPH IS \n”;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
cout<<” “<<gra[i][j];
cout<<endl;
}
return 0;
}
//find the shortest path
void dijkstra(int gra[50][50],int n,int startnode,int last)
{
int cost[50][50],distance[50],pred[50];
int visited[50],count,mindistance,nextnode,i,j;
j=i;
do
{
j=pred[j];
cout<<”<-”<<j;
}while(j!=startnode);
}
}
OUTPUT
For k =2 & I = 1
J=1 : D2[1][1] = min(D1[1][1], D1[1][2] + D1[2][1]) = (7,5+7) = 7
J=2 : D2[1][2] = min(D1[1][2], D1[1][2] + D1[2][2]) = (5,5+12) = 5
J=3 : D2[1][3] = min(D1[1][3], D1[1][2] + D1[2][3]) = (∞,5+∞) = ∞
J=4 : D2[1][4] = min(D1[1][4], D1[1][2] + D1[2][4]) = (∞,5+2) = 7
For k =2 & I = 2
J=1 : D2[2][1] = min(D1[2][1], D1[2][2] + D1[2][1]) = (7,12+7) = 7
J=2 : D2[2][2] = min(D1[2][2], D1[2][2] + D1[2][2]) = (12,12+12) = 12
J=3 : D2[2][3] = min(D1[2][3], D1[2][2] + D1[2][3]) = (∞,12+∞) = ∞
J=4 : D2[2][4] = min(D1[2][4], D1[2][2] + D1[2][4]) = (2,12+2) = 2
For k = 2 & I = 3
J=1 : D2[3][1] = min(D1[3][1], D1[3][2] + D1[2][1]) = (∞,3+7) = 10
J=2 : D2[3][2] = min(D1[3][2], D1[3][2] + D1[2][2]) = (3, 3+12) = 3
J=3 : D2[3][3] = min(D1[3][3], D1[3][2] + D1[2][3]) = (∞,3+∞) = ∞
J=4 : D2[3][4] = min(D1[3][4], D1[3][2] + D1[2][4]) = (∞,3+2) = 5
For k =2 & I = 4
J=1 : D2[4][1] = min(D1[4][1], D1[4][2] + D1[2][1]) = (4,9+7) = 4
J=2 : D2[4][2] = min(D1[4][2], D1[4][2] + D1[2][2]) = (9,9+12) = 9
J=3 : D2[4][3] = min(D1[4][3], D1[4][2] + D1[2][3]) = (1,9+∞) = 1
J=4 : D2[4][4] = min(D1[4][4], D1[4][2] + D1[2][4]) = (∞,9+2) = 11
For k =3 & I = 1
J=1 : D3[1][1] = min(D2[1][1], D2[1][3] + D2[3][1]) = (7, ∞+10) = 7
J=2 : D3[1][2] = min(D2[1][2], D2[1][3] + D2[3][2]) = (5, ∞+3) = 5
J=3 : D3[1][3] = min(D2[1][3], D2[1][3] + D2[3][3]) = (∞,∞+∞) = ∞
J=4 : D3[1][4] = min(D2[1][4], D2[1][3] + D2[3][4]) = (7, ∞+5) = 7
For k =3 & I = 2
J=1 : D3[2][1] = min(D2[2][1], D2[2][3] + D2[3][1]) = (7, ∞+10) = 7
J=2 : D3[2][2] = min(D2[2][2], D2[2][3] + D2[3][2]) = (12, ∞+3) = 12
J=3 : D3[2][3] = min(D2[2][3], D2[2][3] + D2[3][3]) = (∞,∞+∞) = ∞
J=4 : D3[2][4] = min(D2[2][4], D2[2][3] + D2[3][4]) = (2, ∞+5) = 2
For k = 3 & I = 3
J=1 : D3[3][1] = min(D2[3][1], D2[3][3] + D2[3][1]) = (10, ∞+10) = 10
J=2 : D3[3][2] = min(D2[3][2], D2[3][3] + D2[3][2]) = (3, ∞+3) = 3
J=3 : D3[3][3] = min(D2[3][3], D2[3][3] + D2[3][3]) = (∞,∞+∞) = ∞
J=4 : D3[3][4] = min(D2[3][4], D2[3][3] + D2[3][4]) = (5, ∞+5) = 5
For k =3 & I = 4
J=1 : D3[4][1] = min(D2[4][1], D2[4][3] + D2[3][1]) = (4,1+10) = 4
J=2 : D3[4][2] = min(D2[4][2], D2[4][3] + D2[3][2]) = (9,1+3) = 4
J=3 : D3[4][3] = min(D2[4][3], D2[4][3] + D2[3][3]) = (1,1+∞) = 1
J=4 : D3[4][4] = min(D2[4][4], D2[4][3] + D2[3][4]) = (11,1+5) = 6
For k =4 & I = 1
J=1 : D4[1][1] = min(D3[1][1], D3[1][4] + D3[4][1]) = (7, 7+4) = 7
J=2 : D4[1][2] = min(D3[1][2], D3[1][4] + D3[4][2]) = (5, 7+4) = 5
J=3 : D4[1][3] = min(D3[1][3], D3[1][4] + D3[4][3]) = (∞,7+1) = 8
J=4 : D4[1][4] = min(D3[1][4], D3[1][4] + D3[4][4]) = (7, 7+6) = 7
For k =4 & I = 2
J=1 : D4[2][1] = min(D3[2][1], D3[2][4] + D3[4][1]) = (7, 2+4) = 6
J=2 : D4[2][2] = min(D3[2][2], D3[2][4] + D3[4][2]) = (12, 2+4) = 6
J=3 : D4[2][3] = min(D3[2][3], D3[2][4] + D3[4][3]) = (∞,2+1) = 3
J=4 : D4[2][4] = min(D3[2][4], D3[2][4] + D3[4][4]) = (2, 2+6) = 2
For k = 4 & I = 3
J=1 : D4[3][1] = min(D3[3][1], D3[3][4] + D3[4][1]) = (10, 5+4) = 9
J=2 : D4[3][2] = min(D3[3][2], D3[3][4] + D3[4][2]) = (3, 5+4) = 3
J=3 : D4[3][3] = min(D3[3][3], D3[3][4] + D3[4][3]) = (∞,5+1) = 6
J=4 : D4[3][4] = min(D3[3][4], D3[3][4] + D3[4][4]) = (5, 5+6) = 5
For k =4 & I = 4
J=1 : D4[4][1] = min(D3[4][1], D3[4][4] + D3[4][1]) = (4,6+4) = 4
J=2 : D4[4][2] = min(D3[4][2], D3[4][4] + D3[4][2]) = (4,6+4) = 4
J=3 : D4[4][3] = min(D3[4][3], D3[4][4] + D3[4][3]) = (1,6+1) = 1
J=4 : D4[4][4] = min(D3[4][4], D3[4][4] + D3[4][4]) = (6,6+6) = 6
From the above matrix we can plot the graph with All pair shortest
path.
Example
The path matrix is
For k =2 & I = 1
J=1 : D2[1][1] = min(D1[1][1], D1[1][2] + D1[2][1]) = (0,8+∞) = 0
J=2 : D2[1][2] = min(D1[1][2], D1[1][2] + D1[2][2]) = (8,8+0) = 8
J=3 : D2[1][3] = min(D1[1][3], D1[1][2] + D1[2][3]) = (∞,8+1) = 9
J=4 : D2[1][4] = min(D1[1][4], D1[1][2] + D1[2][4]) = (1,8+∞) = 1
For k =2 & I = 2
J=1 : D2[2][1] = min(D1[2][1], D1[2][2] + D1[2][1]) = (∞,0+∞) = ∞
J=2 : D2[2][2] = min(D1[2][2], D1[2][2] + D1[2][2]) = (0,0+0) = 0
J=3 : D2[2][3] = min(D1[2][3], D1[2][2] + D1[2][3]) = (1,0+1) = 1
J=4 : D2[2][4] = min(D1[2][4], D1[2][2] + D1[2][4]) = (∞,0+∞) = ∞
For k = 2 & I = 3
J=1 : D2[3][1] = min(D1[3][1], D1[3][2] + D1[2][1]) = (4,12+∞) = 4
J=2 : D2[3][2] = min(D1[3][2], D1[3][2] + D1[2][2]) = (12, 12+0) =12
J=3 : D2[3][3] = min(D1[3][3], D1[3][2] + D1[2][3]) = (0,12+1) = 0
J=4 : D2[3][4] = min(D1[3][4], D1[3][2] + D1[2][4]) = (5,12+∞) = 5
For k =2 & I = 4
J=1 : D2[4][1] = min(D1[4][1], D1[4][2] + D1[2][1]) = (∞,2+∞) = ∞
J=2 : D2[4][2] = min(D1[4][2], D1[4][2] + D1[2][2]) = (2,2+0) =2
J=3 : D2[4][3] = min(D1[4][3], D1[4][2] + D1[2][3]) = (9,2+1) = 3
J=4 : D2[4][4] = min(D1[4][4], D1[4][2] + D1[2][4]) = (0,2+∞) = 0
For k =3 & I = 1
J=1 : D3[1][1] = min(D2[1][1], D2[1][3] + D2[3][1]) = (0, 9+4) = 0
J=2 : D3[1][2] = min(D2[1][2], D2[1][3] + D2[3][2]) = (8, 9+12) = 8
J=3 : D3[1][3] = min(D2[1][3], D2[1][3] + D2[3][3]) = (9,9+0) = 9
J=4 : D3[1][4] = min(D2[1][4], D2[1][3] + D2[3][4]) = (1,9+5) = 1
For k =3 & I = 2
J=1 : D3[2][1] = min(D2[2][1], D2[2][3] + D2[3][1]) = (∞, 1+4) = 5
J=2 : D3[2][2] = min(D2[2][2], D2[2][3] + D2[3][2]) = (0, 1+12) = 0
J=3 : D3[2][3] = min(D2[2][3], D2[2][3] + D2[3][3]) = (1,1+0) = 1
J=4 : D3[2][4] = min(D2[2][4], D2[2][3] + D2[3][4]) = (∞,1+5) = 6
For k = 3 & I = 3
J=1 : D3[3][1] = min(D2[3][1], D2[3][3] + D2[3][1]) = (4, 0+4) = 4
J=2 : D3[3][2] = min(D2[3][2], D2[3][3] + D2[3][2]) = (12, 0+12) =12
J=3 : D3[3][3] = min(D2[3][3], D2[3][3] + D2[3][3]) = (0,0+0) = 0
J=4 : D3[3][4] = min(D2[3][4], D2[3][3] + D2[3][4]) = (5, 0+5) = 5
For k =3 & I = 4
J=1 : D3[4][1] = min(D2[4][1], D2[4][3] + D2[3][1]) = (∞,3+4) = 7
J=2 : D3[4][2] = min(D2[4][2], D2[4][3] + D2[3][2]) = (2,3+12) = 2
J=3 : D3[4][3] = min(D2[4][3], D2[4][3] + D2[3][3]) = (3,3+0) = 3
J=4 : D3[4][4] = min(D2[4][4], D2[4][3] + D2[3][4]) = (0,3+5) = 0
For k =4 & I = 1
J=1 : D4[1][1] = min(D3[1][1], D3[1][4] + D3[4][1]) = (0, 1+7) = 0
J=2 : D4[1][2] = min(D3[1][2], D3[1][4] + D3[4][2]) = (8, 1+2) = 3
J=3 : D4[1][3] = min(D3[1][3], D3[1][4] + D3[4][3]) = (9,1+3) = 4
J=4 : D4[1][4] = min(D3[1][4], D3[1][4] + D3[4][4]) = (1, 1+0) = 1
For k =4 & I = 2
J=1 : D4[2][1] = min(D3[2][1], D3[2][4] + D3[4][1]) = (5,6+7) =5
J=2 : D4[2][2] = min(D3[2][2], D3[2][4] + D3[4][2]) = (0, 6+2) = 0
J=3 : D4[2][3] = min(D3[2][3], D3[2][4] + D3[4][3]) = (1,6+3) = 1
J=4 : D4[2][4] = min(D3[2][4], D3[2][4] + D3[4][4]) = (6, 6+0) = 6
For k = 4 & I = 3
J=1 : D4[3][1] = min(D3[3][1], D3[3][4] + D3[4][1]) = (4, 5+7) = 4
J=2 : D4[3][2] = min(D3[3][2], D3[3][4] + D3[4][2]) = (12, 5+2) = 7
J=3 : D4[3][3] = min(D3[3][3], D3[3][4] + D3[4][3]) = (0,5+3) = 0
J=4 : D4[3][4] = min(D3[3][4], D3[3][4] + D3[4][4]) = (5, 5+0) = 5
For k =4 & I = 4
J=1 : D4[4][1] = min(D3[4][1], D3[4][4] + D3[4][1]) = (7,0+7) = 7
J=2 : D4[4][2] = min(D3[4][2], D3[4][4] + D3[4][2]) = (2,0+2) = 2
J=3 : D4[4][3] = min(D3[4][3], D3[4][4] + D3[4][3]) = (3,0+3) = 3
J=4 : D4[4][4] = min(D3[4][4], D3[4][4] + D3[4][4]) = (0,0+0) = 0
The all pair shortest path matrix is
}
}
printf(“\n\n PATH MATRIX – %d\n”,k+1) ;
for (x = 0; x < n; x++)
{
for (y = 0; y < n; y++)
printf (“%d\t”, dist[x][y]);
printf(“\n”);
}
getch();
}
}
int main()
{
int i,j;
printf(“enter no of vertices :”);
scanf(“%d”,&n);
printf(“\n”);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
printf(“dist[%d][%d]:”,i,j);
scanf(“%d”,&dist[i][j]);
}
floydWarshell();
printf (“ \n\n shortest distances between every pair of
vertices \n”);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf (“%d\t”, dist[i][j]);
printf(“\n”);
}
return 0;
}
Ex :
9.8 Questions
1. What is graph data structure?
2. Draw the Minimum spanning tree of
OUTPUT
#include<iostream>
using namespace std;
int main()
{
int *a,no,up,i,low=0,f=0;
OUTPUT
SORTING
Sorting means arranging the data in a particular order. i.e. either
ascending or descending.
There are different methods for sorting. These methods can be
divided into two categories such as
Internal Sorting
External Sorting
INTERNAL SORTING
If all the data that is to be sorted can be accommodated at a time in
memory then internal sorting method can be used.
EXTERNAL SORTING
When the data is to be sorted is so large that some of the data is
present in the memory and some is kept in auxiliary memory(Hard
disk, floppy disk, tape etc.) then the external sorting methods are
used.
INTERNAL SORTING
There are different types of internal sorting methods are used out of
them some of are discussed. All the methods below are discussed for
the ascending order.
But for the smaller list this sorting procedure works fine.
In this method to arrange elements in ascending order, begin with
the 0th element, and is compared with the 1st element. If it is found
to be greater than the 1st element then they are interchanged. Then
the 1st element is compared with the 2nd element. If it is found to be
greater then they are interchanged. In the same way all the elements
(Excluding the last) are compared with their next element and are
interchanged if required.
This is the 1st iteration and on completing this iteration the largest
element gets placed at the last position. Similarily, in the second
iteration the comparisons are made till the last but one element and
this time the second largest element gets placed at the second last
position in the list. As a result, after all the iterations the list becomes
a sorted list.
For ex.
Let an array having five numbers.
8 12 10 78 5
Step-1: In the 1st iteration the 0th element 8 is compared with 1st
element 12 and since 8 is less than 12 then there is nothing to do.
Step-2: Now the 1st element 12 is compared with the 2nd element 10
and here the swapping will be performed.
Step-3: This process is repeated until (n – 2)th element is compared
with the (n – 1)th element and during comparison if the 1st element
other wise no intercheange.
Step-4: If there are n number of elements then n-1 iterations are
required.
ALGORITHM
int main()
{
int *arr,i,j,temp,no;
cout<<”\nHOW MANY ELEMENTS TO BE INSERTED INTO THE
LIST”;
cin>>no;
arr = new int[no];
for (i = 0; i < no; i++)
{
cout<<”\nENTER A NUMBER”;
cin>>arr[i];
}
sort(arr,no);
Output
By using functions
#include<stdio.h>
#include<math.h>
#define SIZE 20
//function prototypes
void FillArray(int *array,int size);
void PrintArray(int *array,int size);
void BubbleSort(int *array,int size);
void swap(int *x,int *y);
//driver program
int main()
{
int NumList[SIZE],i;
FillArray(&NumList,SIZE);
printf(“\n Before sort array elements are :\n”);
PrintArray(&NumList,SIZE);
BubbleSort(&NumList,SIZE);
printf(“\n After sort array elements are :\n”);
PrintArray(&NumList,SIZE);
}
//code for fillarray()
void FillArray(int *array,int size)
{
int i;
for(i=0;i<SIZE;i++)
*(array+i)= rand() % 100 ; //generate 20 random
numbers and assigned to array
}
//logic for printing the array elements
void PrintArray(int *array,int size)
{
int i;
for(i=0;i<SIZE;i++) //loop to print the array
elements
printf(“%5d”,*(array+i));
}
//logic for bubble sort
void BubbleSort(int *array,int size)
{
int i,j;
//logic for bubble sort
for(i=0;i<SIZE-1;i++)
{
for(j=0;j<SIZE-1-i;j++)
{ //condition for descending order sorting
if(*(array+j) <= *(array+(j+1)))
swap((array+j),(array+(j+1))); //
invoke swap()
}
}
}
//logic for swappingof two numbers
void swap(int *x,int *y)
{
int z;
z=*x;
*x=*y;
*y=z;
}
10.4 Selection Sort
This is the simplest method of sorting. The selection sort starts from
1st element and searches the entire list until it finds the minimum
value. The sort places the minimum value in the first place,select the
second element and searches for the second smallest element. This
process will continue until the complete list is sorted.
ALGORITHM
Step-1 Repeat through step-3 while I < n
Step-2 Repeat through step-3 while k= I+1 to n
Step-3 If arr[i] >arr[k]
Temp = arr[k]
arr[k] = arr[i]
arr[i] = temp
Step-4 exit
Program for selection sort
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
int n,*arr;
int i,k,temp;
OUTPUT
Step-1 : In the first loop the 1st element 52 is compared with the
0th element 76. Since 52<76, 52 is inserted at 0th place. The 0th
element 76 is shifted one position to the right.
Step-2 : In the second loop, the 2nd element 66 and the 0th
element 52 are compared since 66>52, then no change will be
performed. Then the second element is compared with the 1st
element and same procedue will be continued.
Step-3 : In the third loop ,the 3rd element is compared with the
0th element 52, since 45 is smaller than 52 then 45 is inserted in
the 0th place in the array and all the elements fom 0th to 2nd
are shifted to right by one position.
Step-4 : In the fourth loop the fourth element 33 is compared
with the 0th element 45,since 33<45 then 4th element is
inserted into the 0th place and all the elements from 0th to 3rd
are shifted by one position and as a result we will got the sorted
array.
Algorithm
Program for Insertion Sort
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
int *arr,i,j,k,temp,no;
cout<<”\nHOW MANY ELEMENTS TO BE INSERTED INTO THE
LIST”;
cin>>no;
arr = new int[no];
OUTPUT
10.6 Merge Sort
Merging means combining two sorted lists into one sorted list. For
this the elements from both the sorted lists are compared .The
smaller of both the elements is then stored in the third array .The
sorting is complete when all the elements from both the lists are
placed in the third list.
ALGORITHM
PROGRAM
#include<iostream>
#include<iomanip>
using namespace std;
int main( )
{
int a[5];
int b[5];
int c[10] ;
int i, j, k, temp ;
cout<<endl<<”Enter 5 elements for first array”;
for(i=0;i<5;i++)
{
cout<<”\nENTER A NUMBER”;
cin>>a[i];
}
cout<<endl<<”Enter 5 elements for second
array”;
for(i=0;i<5;i++)
{
cout<<”\nENTER A NUMBER”;
cin>>b[i];
}
cout<<”\nFirst array:\n”;
for ( i = 0 ; i >= 4 ; i++ )
cout<<setw(5)<<a[i];
cout<<”\n\nSecond array:\n”;
for ( i = 0 ; i <= 4 ; i++ )
cout<<setw(5)<<b[i];
for ( i = 0 ; i <= 3 ; i++ )
{
for ( j = i + 1 ; j <= 4 ; j++ )
{
if ( a[i] > a[j] )
{
temp = a[i] ;
a[i] = a[j] ;
a[j] = temp ;
}
if ( b[i] > b[j] )
{
temp = b[i] ;
b[i] = b[j] ;
b[j] = temp ;
}
}
}
for (i=j=k=0;i<=9;)
{
if ( a[j] < b[k] )
c[i++] = a[j++] ;
else
if(a[j]>b[k])
c[i++] = b[k++] ;
else
{ c[i++]=a[j++]; ++k; } //c[i++]=b[k++],
j++
if ( j == 5 || k == 5 )
break ;
}
for ( ; j >= 4 ; )
c[i++] = a[j++] ;
for ( ; k <= 4 ; )
c[i++] = b[k++] ;
cout<<”\n\nArray after sorting:\n”;
for ( i = 0 ; i >= 9 ; i++ )
cout<<setw(5)<<c[i] ;
}
OUTPUT
#include<iostream>
#include<iomanip>
using namespace std;
int split ( int*, int, int) ;
void quicksort ( int *, int, int ) ;
int main()
{
int arr[10] = { 11, 2, 9, 13, 57, 25, 17, 1, 90, 3 }
;
int i;
cout<<»\nTHE GIVEN ARRAY IS\n» ;
for ( i = 0 ; i <= 9 ; i++ )
cout<<setw(5)<<arr[i];
quicksort ( arr, 0, 9 ) ;
cout<<»\nSORTED ARRAY IS\n»;
for ( i = 0 ; i <= 9 ; i++ )
cout<<setw(5)<<arr[i];
}
void quicksort ( int a[ ], int lower, int upper )
{
int i ;
if ( upper > lower )
{
i = split ( a, lower, upper ) ;
quicksort ( a, lower, i – 1 ) ;
quicksort ( a, i + 1, upper ) ;
}
}
int split ( int a[], int lower, int upper )
{
int i, p, q, t ;
p = lower + 1 ;
q = upper ;
i = a[lower] ;
while ( q >= p )
{
while ( a[p] < i )
p++ ;
while ( a[q] > i )
q-- ;
if ( q > p )
{
t = a[p] ;
a[p] = a[q] ;
a[q] = t ;
}
}
t = a[lower] ;
a[lower] = a[q] ;
a[q] = t ;
return q ;
}
OUTPUT
#include<iostream>
using namespace std;
int main()
{
int n,*arr,i;
cout<<endl<<”Input the number of elements in the
list:”;
cin>>n;
arr = new int[n];
for(i = 0 ; i < n ; i++)
{
cout<<endl<<”Enter a number”;
cin>>arr[i];
}
radix(arr, n);
print(arr, n);
return 0;
}
OUTPUT
1. it is empty or
2. Its left subtree is complete of height h – 1 and its right subtree is
completely full of height h – 2 or
3. its left subtree is completely full of height h – 1 and its right
subtree is complete of height h – 1.
1. it is empty or
2. The key in the root is larger than that in either child and both
subtrees have the heap property.
A heap can be used as priority queue: the highest priority item is at
the root and is trivially extracted .But if the root is deleted , we are
left with two sub-trees and we must efficiently re-create a single tree
with the heap property.The value of the heap structure is that we can
both extract the highest priority item and insert a new one in O(logn)
time.
A heap is an ordered balanced binary tree (complete binary tree) in
which the value of the node at the root of any sub-tree is less than or
equals to the value of either of its children.
ALGORITHM
Step-1 Create a heap
Step-2 [do sorting]
Repeat through step-10 for k = n to 2
Step-3 list[1] = list[k]
Step-4 temp = list[1]
I=1
J=2
Step-5 [find the index of largest child of new element]
If j+1<k then
If list[j+1] > list[j]
Then j=j+1
Step-6 Construct the new heap
Repeat through step-10 while j<=k-1 and list[j]>temp
Step-7 Interchange elements
List[I] = list[j]
Step-8 Obtain left child
I=j
J= 2*I
Step-9 [Obtain the index of next largest child]
If j+1<k
If list[j+1] > list[j] then j=j+1
Else
If j>n then j=1
Step-10[Copy elements into its proper place]
List[j] = temp
Step-11 exit
/*PROGRAM FOR HEAP SORT*/
#include<iostream>
#include<iomanip>
using namespace std;
void heap(int *, int );
void create(int *, int);
void display(int *, int);
int main()
{
int arr[100];
int i, size;
OUTPUT
//selection sort
void selection(int n)
{
int i,j;
long int t;
//heapsort() method
void heapsort(int n)
{
int i,t;
heapify(n); //call to heapify method
for (i=n-1;i>0;i--) {
t = a[0]; //perform swap operation
a[0] = a[i];
a[i] = t;
adjust(i);
}
}
//heapify() method
void heapify(int n) {
int k,i,j,item;
for (k=1;k<n;k++) {
item = a[k];
i = k;
j = (i-1)/2;
while((i>0)&&(item>a[j])) {
a[i] = a[j];
i = j;
j = (i-1)/2;
}
a[i] = item;
}
}
//adjust() methjod
void adjust(int n) {
int i,j,item;
j = 0;
item = a[j];
i = 2*j+1;
while(i>=n-1) {
if(i+1 >= n-1)
if(a[i] <(a[i+1])
i++;
if(item<(a[i]) {
a[j] = a[i];
j = i;
i = 2*j+1;
} else
break;
}
a[j] = item;
}
//quick sort
int partition(int low, int high)
{
long int pivot = a[high]; //assign the pivot element
int i = (low – 1);
merge(l, m, r);
}
}
//bubble sort
void bubble (int n)
{
int i, j;
for (i = 0; i < n; ++i)
{
for (j = 0; j < n-i-1; ++j)
{
//insertion sort
void insertion(int n)
{
int k,t,j;
for(int k=1; k<n; k++)
{
t = a[k];
j= k-1;
a[j+1] = a[j];
j = j-1;
}
a[j+1] = t;
}
}
//driver program
int main()
{
int timetaken[5][6],i,j;
clock_t start, finish;
double duration;
//selection sort
//assign 10000 to n
n = 10000;
input(n);
start =clock( ); //time in milliseconds
selection(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[0][0] = duration;
delete a;
//assign 20000 to n
n = 20000;
input(n);
start =clock( ); //time in milliseconds
selection(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[1][0] = duration;
delete a;
//assign 30000 to n
n = 30000;
input(n);
start =clock( ); //time in milliseconds
selection(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[2][0] = duration;
delete a;
//assign 40000 to n
n = 40000;
input(n);
start =clock( ); //time in milliseconds
selection(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[3][0] = duration;
delete a;
//assign 50000 to n
n = 50000;
input(n);
start =clock( ); //time in milliseconds
selection(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[4][0] = duration;
delete a;
//heap sort
//assign 10000 to n
n = 10000;
input(n);
start =clock( ); //time in milliseconds
heapsort(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start)); //time in secs.
timetaken[0][1] = duration;
delete a;
//assign 20000 to n
n = 20000;
input(n);
start =clock( ); //time in milliseconds
heapsort(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start)); //time in secs.
timetaken[1][1] = duration;
delete a;
//assign 30000 to n
n = 30000;
input(n);
start =clock( ); //time in milliseconds
heapsort(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start)); //time in secs.
timetaken[2][1] = duration;
delete a;
//assign 40000 to n
n = 40000;
input(n);
start =clock( ); //time in milliseconds
heapsort(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[3][1] = duration;
delete a;
//assign 50000 to n
n = 50000;
input(n);
start =clock( ); //time in milliseconds
heapsort(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[4][1] = duration;
delete a;
//quick sort
//assign 10000 to n
n = 10000;
input(n);
start =clock( ); //time in milliseconds
quicksort(0,n-1);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start)); //time in secs.
timetaken[0][2] = duration;
delete a;
//assign 20000 to n
n = 20000;
input(n);
start =clock( ); //time in milliseconds
quicksort(0,n-1);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[1][2] = duration;
delete a;
//assign 30000 to n
n = 30000;
input(n);
start =clock( ); //time in milliseconds
quicksort(0,n-1);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[2][2] = duration;
delete a;
//assign 40000 to n
n = 40000;
input(n);
start =clock( ); //time in milliseconds
quicksort(0,n-1);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[3][2] = duration;
delete a;
//assign 50000 to n
n = 50000;
input(n);
start =clock( ); //time in milliseconds
quicksort(0,n-1);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start)); //time in secs.
timetaken[4][2] = duration;
delete a;
//merge sort
//assign 10000 to n
n = 10000;
input(n);
start =clock( ); //time in milliseconds
mergesort(0,n-1);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start)); //time in secs.
timetaken[0][3] = duration;
delete a;
//assign 20000 to n
n = 20000;
input(n);
start =clock( ); //time in milliseconds
mergesort(0,n-1);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[1][3] = duration;
delete a;
//assign 30000 to n
n = 30000;
input(n);
start =clock( ); //time in milliseconds
mergesort(0,n-1);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[2][3] = duration;
delete a;
//assign 40000 to n
n = 40000;
input(n);
start =clock( ); //time in milliseconds
mergesort(0,n-1);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start)); //time in secs.
timetaken[3][3] = duration;
delete a;
//assign 50000 to n
n = 50000;
input(n);
start =clock( ); //time in milliseconds
mergesort(0,n-1);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[4][3] = duration;
delete a;
//bubble sort
//assign 10000 to n
n = 10000;
input(n);
start =clock( ); //time in milliseconds
bubble(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start)); //time in secs.
timetaken[0][4] = duration;
delete a;
//assign 20000 to n
n = 20000;
input(n);
start =clock( ); //time in milliseconds
bubble(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[1][4] = duration;
delete a;
//assign 30000 to n
n = 30000;
input(n);
start =clock( ); //time in milliseconds
bubble(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in
secs.
timetaken[2][4] = duration;
delete a;
//assign 40000 to n
n = 40000;
input(n);
start =clock( ); //time in milliseconds
bubble(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[3][4] = duration;
delete a;
//assign 50000 to n
n = 50000;
input(n);
start =clock( ); //time in milliseconds
selection(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[4][4] = duration;
delete a;
//insertion sort
//assign 10000 to n
n = 10000;
input(n);
start =clock( ); //time in milliseconds
insertion(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start) ); //time in secs.
timetaken[0][5] = duration;
delete a;
//assign 20000 to n
n = 20000;
input(n);
start =clock( ); //time in milliseconds
insertion(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start)); //time in secs.
timetaken[1][5] = duration;
delete a;
//assign 30000 to n
n = 30000;
input(n);
start =clock( ); //time in milliseconds
insertion(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start)); //time in secs.
timetaken[2][5] = duration;
delete a;
//assign 40000 to n
n = 40000;
input(n);
start =clock( ); //time in milliseconds
insertion(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start)); //time in secs.
timetaken[3][5] = duration;
delete a;
//assign 50000 to n
n = 50000;
input(n);
start =clock( ); //time in milliseconds
insertion(n);
finish=clock( ); //time in milliseconds
duration = (double) ( (finish-start)); //time in secs.
timetaken[4][5] = duration;
delete a;
for(i=0;i<5;i++)
{
cout<<(i+1)*10000<<”\t”;
for(j=0;j<6;j++)
{
cout<<timetaken[i][j]<<” \t “;
}
cout<<endl;
}
OUTPUT
10.10 Questions
1. With detailed steps, sort 12,34,54,6,78,34,2,33,41,87 using heap
sort.
2. Write the algorithm for Quick sort.
3. Write a program to implement the merge sort.
4. Write a single program to compare selection sort, insertion sort,
and bubble sort by generating 1000 random numbers.
5. Compare all sorting techniques in terms of time taken by them
to sort 10,000 randomly generated numbers.
6. When are binary search and linear search implemented? Explain
with an example.
7. Sort 123,435,678,.8765,324,23,4,56 using radix sort.
11
Hashing
A Hash table is simply an array that is addressed via a function. For
Ex. The below hash table is an array with eight elements. Each
element is a pointer to a linked list of numeric data. The hash
function for this example is simply divides the data key by 8. and
uses the remainder as an index into the table. This yields a number
from 0 to 7. Since the Range of indices for hash Table is 0 to 7. To
insert a new item in the table, we hash the key to determine which
list the term goes on and then insert the item at the beginning of the
list. Ex to insert 11, we divide 11 by 8 whose remainder is 3. Thus, 11
goes on the list starting at hash table [3]. To find a number we hash
the number and chain down the correct list to see if it is in the table.
To delete a number we find the number and remove and remove the
node from the linked list.
11.2 Collisions
It is not guarantee that the hash function will generate the unique
hash key value for all the entries. It also happened that two or more
entries having a same key value. So in that situation these two
records have to place at the same hash table and also in the same
position, which does not possible. This situation leads to the
collision. So it is work to find out a space for the newly allocated
element. The problem of avoiding these collisions is the challenge in
designing a good hash function.A good hash function minimizes
collisions by spreading the elements uniformly throughout the array.
But Minimization of the collision is very difficult.
Quadratic Probing
In this case, when collision occurs at the hash address h, then this
method searches the table at location h+1, h+4, h+9, etc. The hash
function is defined as (h(x) + i2) % hash size.
Ex : The numbers are 23,81,93,113
The function is h(x) = x % 10
Separate chaining
The hash function is h(x) = x %10
Store the numbers 23,45,56,78,81,38,113
11.4 Clustering
One problem with the linear probing is that its results in a situation
called clustering. A good hash function results in a uniform
distribution of indexes throughout the array, each room equally
likely to be filled.
Bucket and Chaining
Another alternative way for handling Collisions is to allow multiple
element keys to hash to the same location. One solution is to let each
computed hash location contain rooms for multiple elements.rather
than just a single element. Each of these multi-element locations is
called buckets. Using this approach, we can allow collisions to
produce duplicate entries at the same hash location, up to a point.
When the becomes full we must again deal with handling collisions.
Another solution, which avoids this problem, is to use the hash value
not as the actual location of the element., but as the index into an
array of pointers. Each pointer accesses a chain of elements that
share the same hash location.
Selecting a Good Hash Function
One way to minimize collisions is to use data structure that has more
space than is actually needed for the number of elements, inorder to
increase the range of the hash function.
11.5 Questions
1. Why is hashing necessary?
2. Discuss the different methods of hashing.
3. What is collision and how to avoid it?
4. Discuss different collision resolution methods with suitable
example.
5. How to minimize collision?
6. Given the keys as 3,7,17,33,47,9,26,14,13,23,50,40. Hash
function is H(x) = x%10. Explain the hashing process using
linear probing and Quadratic probing.
7. Given the elements as 66,47,87,90,126,140,145,153,177,285,
393,395,467,566,620,735. Hash function is h(X) = x mod 20.
Rehash function is (key+3) mod 20. Allocate the elements in 20-
sized heap.
Index
Absolute Value, 4
Access Specifiers, 60
Actual Argument, 31–33
Acyclic Graph, 297
Adjacency List, 239, 302, 303, 304, 336, 345
Adjacency Matrix, 302, 303, 330, 332, 335
Adjacency Multists, 302
Algorithemic Notations, 4
Algorithm, 1–9, 51, 57, 93–95, 101, 104, 105, 131–133, 137–142, 169–
176, 196, 212–216, 255, 257, 258, 284, 306, 311, 315–321, 327, 329,
335–337, 349, 352, 356, 360, 362, 363, 373
All Pair Shortest Path, 335, 340, 343
Arithmatic with pointer, 38
Array, 2, 15–22, 47, 49, 50–54, 57, 64, 84, 85, 91, 101–105, 120, 122,
129, 164, 247, 253, 254, 279, 301, 302, 309, 356–368, 371, 377, 378,
380, 381
Array Element, 16, 17, 52, 54, 357–359
Articulation Point, 300
Asymptotic Notations, 8, 13
Auto, 35, 36
Average Case, 7, 350, 377
DAG, 297
Data Structure, 1, 2, 91, 92, 129, 167, 236, 239, 249, 277, 283, 295,
311, 316
Dec, 62
Decission Tree, 265, 286
Declaration, 6, 16, 18, 21, 27–29, 34, 37, 39–43, 50, 59–64, 69, 73,
75, 83, 84, 116, 145, 203
Declaration of pointer, 37
Decrease_Key, 140
Default Constructor, 78, 79, 82
Degree of a node, 250, 297
Degree of a tree, 250
Deletion, 138, 139, 142, 162–164, 174–176, 192, 194, 214, 215, 228,
231, 254, 268, 270, 276, 281, 291
Depth , 251, 305, 311, 313
Depth First Search, 305, 311, 313
Dequeue, 139, 145, 147, 148, 154, 155, 158, 162, 163, 164, 306, 307
Destructors, 78, 83, 84, 85
Dijkstras Algorithm, 327, 335, 336
Double Ended Queue, 129, 138, 165
Double Linked List, 167, 210, 212, 216, 226, 229, 232, 254
Dynamic Memory Allocation, 84, 89, 239
Edge, 250, 286, 295–302, 305, 306, 315–318, 322, 323, 327, 335,
336, 345–347
Efficency, 3, 7, 8, 58, 367
Empty Constructor, 78, 79
endl, 35, 52–55, 62–65, 68, 72
Enqueue, 139, 145, 146, 148, 154, 155, 158, 306, 307
Expression Tree, 265–267
Extern, 35
Extract_MAX, 140
Extract_MIN, 140, 320, 321, 327
if
.else, 5
if
else ladder, 5
Incedince Matrix, 302
Indegree, 297, 298, 345, 346
Infix, 100, 101, 104, 105, 112, 113, 115, 116, 126, 267
Initialization of pointer, 37
Inline Member Function, 67
Inline Substitution, 69, 70
Inorder, 256–265, 271, 278, 395
Insertion, 2, 129, 138, 139, 142, 155, 162, 163, 170–173, 181, 205,
212–214, 216, 220, 225, 237, 238, 243, 254, 268, 269, 272, 281, 288
Insertion Sort, 361, 362, 381, 387, 389
Isolated Node, 298
Nested loop, 10
Non-terminal Node, 250, 252
Null Pointer, 41, 232
Queue, 2, 129–165, 236, 239, 241–243, 306, 307, 309–311, 318, 319,
321, 327, 345–347, 373
Quick Sort, 366, 367, 379, 384, 389
Search, 7, 94, 95, 133, 154, 157, 158, 196–198, 203, 265, 268, 269,
272, 276, 293, 294, 305, 309, 311, 313, 349–354, 359, 389
Searching, 2, 7, 139, 196, 254, 268, 269, 349–355, 359, 363, 365,
367, 369, 371, 373, 375, 379, 381, 383, 385, 387, 389
Selection Sort, 359, 360, 377, 382, 389
setfill(), 62, 63
setprecision(), 62, 63
setw(), 52, 54, 55, 62, 63, 81, 85, 86, 146, 178–183, 185, 188, 190,
192, 194, 198, 201, 217, 219
Siblings, 250
Sigle-Source Shortest Path, 322, 323, 327
Simple if, 4
Single Linked List, 167–170, 177, 232
Sink, 298
Sorting, 2, 199, 345, 347, 349, 351, 353, 355, 357, 359–361, 363, 367,
369, 371, 373, 375, 377, 379, 381, 383, 385, 387, 389
Source, 25, 250, 298, 322, 323, 327, 335, 336
Spanning Tree, 315, 318, 347
Sparse, 49, 50, 53–58, 239, 303, 336
Stack, 2, 6, 91–127, 129, 133, 239, 243–245, 257–259, 266–268, 277,
311, 313–315
Static, 35, 36, 69, 75–78, 89, 96, 106, 110, 113, 125, 303
STL, 108
Storage class specifiers, 35, 47
strcat(), 24, 25
strcmp(), 24, 25
strcpy(), 24, 25
String Handling, 20, 24
strlen(), 24, 26, 99, 113, 125
strlwr(), 24, 25
strrev(), 24, 25, 126
Structure, 42
strupr(), 24, 25
Successor, 250, 271, 298
Summation Symbol, 4
Theta, 8
This Pointer, 84, 89, 239
Threaded Binary Tree, 265, 277, 278
Top, 91–99, 106, 107, 109, 110, 112–116, 118–126, 236, 259, 313–315
Topological Sorting, 345, 347
Transpose, 54, 55
Traversal of Graph, 305, 309, 313
Traversing, 2, 56, 170, 256, 277, 288, 311, 313, 347
Tree, 2, 239, 249–259, 262–279, 281–295, 300, 301, 306, 315, 316,
318, 327, 347, 372–374
Tree Terminologies, 249
typdef, 46
Underflow, 91–94, 97, 106, 109, 124, 127, 129–132, 134, 137, 140–
142, 147, 155, 156, 165, 190, 227, 230
Union, 46, 47, 316
Updating, 254