Data Structure-ECE NOTES
Data Structure-ECE NOTES
(Open Elective-I)
3 0 0 3
Course objectives:
Solve problems using data structures such as linear lists, stacks, queues, hash table
Be familiar with advanced data structures such as balanced search trees, AVL Trees, and B trees.
Course Outcomes: By the end of the course student will be able to
Select appropriate data structures as applied to specific problem definition.
Summarize and understand the practical applications of several advanced techniques like Hashing and Analyzing
and Implement appropriate sorting/searching technique for given problems
Demonstrate the operations such as Insertion, Deletion and Search on Data structures like Binary Search Tree and
solve the problems.
Demonstrate the operations such as Insertion, Deletion and Search on Advanced Data Structures like Heaps, AVL
trees and B Trees.
Comparisons of trees like Red Black trees and B-Trees etc. and priority queue operations.
UNIT-1: Introduction to data Structures: Abstract Data Types(ADTs), The List ADT: Simple Array implementation of lists,
Simple Linked Lists, Double Linked Lists, Circular Linked Lists. The Stack ADT: The Stack Model, Implementation of Stacks,
Applications of Stack. The Queue ADT: Queue Model, Array implementation of Queue, Application of Queues. Stacks and
Queue implementation using linked list.
UNIT-2: Searching: List Searches, Linear and Binary Search Methods,
Sorting: Selection Sort, Insertion Sort, Quick Sort, Merge Sort and Heap Sort.
Hashing: Hashing Function, Separate Chaining, Collision Resolution-Separate Chaining.
UNIT-3: Trees: Binary Trees-Implementation, Expression Trees. Binary Search Trees-find, findMin and findMax, insert,
delete operations.
UNIT-4: Trees: AVL Trees-Single and Double Rotation, Operations.
B-Tree: searching, insertion, deletion
UNIT-5: Trees: Introduction to Red-black, splay trees and Comparison of Search Trees
Priority Queues: Priority Queue Models, Simple Implementations.
Text books:
1. Data Structures and Algorithm Analysis, Edition, mark Allen Weiss, Pearson.
2. Data structures: A Pseudo Code Approach with c, Edition, Richard F.gilberg, & Behrouz A. Forouzon, Cengage
Reference Books:
1. Data Structures, Algorithms and Applications in Java,2/e, Sartaj Sahani, University Press.
2. Data Structures using c, 2/e, Reema Thareja
UNIT-1: Introduction to data Structures: Abstract Data Types(ADTs), The List ADT: Simple Array implementation of
lists, Simple Linked Lists, Double Linked Lists, Circular Linked Lists. The Stack ADT: The Stack Model, Implementation of
Stacks, Applications of Stack. The Queue ADT: Queue Model, Array implementation of Queue, Application of Queues.
Stacks and Queue implementation using linked list.
Introduction to data Structures: A data structure is a specialized format for organizing, processing, retrieving and storing
data. Every data structure is used to organize the large amount of data. Every data structure follows a particular principle.
BASIC CONCEPT OF DATA STRUCTURES: Data structure is defined a set of data elements along with their operations that
show the relationship among these elements. Data structure determines the interface that enables you to add, delete,
traverse, search and count the elements of data structure. Data structures are two types:
Linear
Non-linear
In a linear data structure, the data elements are organized in a sequence or linear list. A data structure is a non-linear data
structure if its elements do not form a sequence or a linear list.
You can perform various operations on data structures such as insertion, deletion, medication and traversal of the values
present in these data elements. The manner in which these operations are performed on data structures is defined by the
use of algorithms. You can use various types of data structures that help in organizing and sorting the data in an ordered
and controlled way. Various types of data structure are:
Arrays, which store a collection of related values of the same data type.
Linked list, which is a finite sequence of nodes, each of which contains a pointer field to the next node.
Stacks, which are an ordered collection of elements that you can access only from one end, called the top of stack
Queues, which are an ordered collection of elements in which elements are inserted from one end and deleted
from another end.
Trees, which represent different data elements in form of a tree using nodes and links.
Graphs, which represent data inform of a graph using vertices and edges.
Data Structure Operations:
The data that you use in the data structures is manipulated by a number of operations. These operations are:
Traversing:, which allows you to access each record only once so that you can process certain items in the record.
Searching, which allows you to search the location of the records that confirms one or more than one condition
Inserting, which allows you to add new record to the structure.
Deleting, which allows you to remove a record from the structure.
You may need two or more operations in certain conditions. For example, if you want to delete a record then you have to
first search the location of the record.
The following are two more operations that you can use in certain conditions:
Sorting helps to arrange the data in ascending or descending order.
Merging helps to combine the records of two files in a single sorted file.
Problem Analysis:
Problem analysis refers to understanding and resolving a problem, which may occurs while handling the data structure and
performing operations on it. The various steps involved in problem analysis are:
1. Understanding the goals of the system;
2. Understanding the processes, which take place to accomplish the task;
3. Defining the system boundary and constraints;
4. Identifying the problem in the system; and
5. Defining the solution for the problem
ALOGORITHMS: An algorithm is a sequence of steps to be performed to execute a program successfully or to complete a
given task. When this sequence of steps is performed on sample data, the result or output obtained is the expected result of
algorithm. The algorithms are generally expressed in natural language and pseudo code form. They can also be
implemented as computer programs using a programming language in the form of neural network, as an electrical circuit or
in a mechanical device. Flow charts are used to graphically represent an algorithm.
The representation of algorithms is generally classified into following categories:
High-Level Description: it describes the algorithm and is not concerned with the implementation details of the
algorithm
Implementation Description: It is concerned with the implementation level details, i.e, how the data that is being
used in the algorithm stores data physically. The details about data in different states or the transition function are
not taken into account.
Formal description: It gives the highest level of description. The information about data in every state is given with
the help of state table.
Consider an algorithm to find the largest number among all the given numbers. The following code shows the algorithm to
find the largest number
Algorithm Largest Number
input: A non-empty list of L numbers
output: The largest number in the non-empty list f L
numbers
largest<-
for each number in the list, L , do
if each item > largest, then
largest <- the item
return largest
In the above code, the value of the item is assigned to the largest and the return keyword terminates the algorithm and
gives the largest value as the output.
An algorithm must have the following properties:
Input: The data, which is externally supplied to the algorithm, is called input.
Output: The information, which is supplied by the algorithm, is called output. Each algorithm must have at least
one input and one output.
Finiteness: An algorithm must terminate after a finite number of steps. The statements containing stop, return or
halt keywords denotes the termination of an algorithm.
Definiteness: Each step in the algorithm must be clear and unambiguous.
Algorithm Complexity: The efficient of the algorithm depends on two essential elements-time and space. The complexity of
an algorithm is the function that provides the running time and space for data depending on the size provided by you.
Sometimes you may need a time-space trade-off that increases the amount of space to store the data. Using time-space
trade –off, you may be able to reduce the time required for processing the data or you may increase the time required for
processing the data.
The complexity of the algorithm P is a function g(n) that provides you with the running time and space of operations
performed by an algorithm when the input size is n. The storage space for an algorithm is a multiple of the data size n. You
need to use the following two cases to investigate the complexity theory:
Worst case: The worst case occurs when the item is the last element in the array or the item is not available. In this
situation ,you have
C(n)=n
Average case: In this case, the item is present in the array and can occur at any position in the array. Then,
C(n)=1.1\n+2.1\n+………n.1\n
=(1+2+3+…..+n).1\n
=n(n+1)\2.1\n
=n+1\2
Asymptotic Notations Following are the commonly used asymptotic notations to calculate the running time complexity of
an algorithm.
Ο Notation
Ω Notation
θ Notation
Big Oh Notation, Ο:
The notation Ο(n) is the formal way to express the upper
bound of an algorithm's running time. It measures the
worst case time complexity or the longest amount of time
an algorithm can possibly take to complete.
For example, for a function f(n)
Ο(f(n)) = { g(n) : there exists c > 0 and n0 such that f(n) ≤
c.g(n) for all n > n0. }
Omega Notation, Ω :
The notation Ω(n) is the formal way to express the lower
bound of an algorithm's running time. It measures the best
case time complexity or the best amount of time an
algorithm can possibly take to complete
For example, for a function f(n).
Ω(f(n)) ≥ { g(n) : there exists c > 0 and n0 such that
g(n) ≤ c.f(n) for all n > n0. }
Theta Notation, θ :
The notation θ(n) is the formal way to express both the
lower bound and the upper bound of an algorithm's
running time. It is represented as follows :
θ(f(n)) = { g(n) if and only if g(n) = Ο(f(n)) and g(n) = Ω(f(n))
for all n > n0. }
Need of Data Structures: As applications are getting complexes and amount of data is increasing day by day, there may
arise the following problems:
Processor speed: To handle very large amount of data, high speed processing is required, but as the data is growing day by
day to the billions of files per entity, processor may fail to deal with that much amount of data.
Data Search: Consider an inventory size of 106 items in a store; If our application needs to search for a particular item, it
needs to traverse 106 items every time, results in slowing down the search process.
Multiple requests: If thousands of users are searching the data simultaneously on a web server, then there are the chances
that a very large server can be failed during that process
In order to solve the above problems, data structures are used. Data is organized to form a data structure in such a way that
all items are not required to be searched and required data can be searched instantly.
Advantages of Data Structures:
Efficiency: Efficiency of a program depends upon the choice of data structures. For example: suppose, we have some data
and we need to perform the search for a particular record. In that case, if we organize our data in an array, we will have to
search sequentially element by element. Hence, using array may not be very efficient here. There are better data structures
which can make the search process efficient like ordered array, binary search tree or hash tables.
Reusability: Data structures are reusable, i.e. once we have implemented a particular data structure, we can use it at any
other place. Implementation of data structures can be compiled into libraries which can be used by different clients.
Abstraction: Data structure is specified by the ADT which provides a level of abstraction. The client program uses the data
structure through interface only, without getting into the implementation details.
TYPES OF DATA STRUCTURES:
1. Primitive Data Structures: Primitive data structures are the basic data structures and are directly operated upon by the
machine instructions are known as Primitive Data Structures. They are
1.Integer 2.Float 3.Char 4.Double 5.Boolean
2: Non-Primitive Data Structures: The Data structures that are not directly processed by machine using its instructions are
known as Non-Primitive Data Structures.
Non-Primitive Data Structures are
1. Linear Data Structure 2.Non - Linear Data Structure
Linear Data Structure: A data structure is called linear if all of its elements are arranged in the linear order. In linear data
structures, the elements are stored in non-hierarchical way where each element has the successors and predecessors
except the first and last element.
Types of Linear Data Structures are given below:
Arrays: An array is a collection of similar type of data items and each data item is called an element of the array. The data
type of the element may be any valid data type like char, int, float or double.
The elements of array share the same variable name but each one carries a different index number known as subscript. The
array can be one dimensional, two dimensional or multidimensional.
The individual elements of the array age are:
age[0], age[1], age[2], age[3],......... age[98], age[99].
Stack: Stack is a linear list in which insertion and deletions are allowed only at one end, called top. A stack is an abstract
data type (ADT), can be implemented in most of the programming languages. It is named as stack because it behaves like a
real-world stack,
for example: - piles of plates or deck of cards etc.
Queue: Queue is a linear list in which elements can be inserted only at one end called rear and deleted only at the other
end called front.
It is an abstract data structure, similar to stack. Queue is opened at both end therefore it follows First-In-First-Out (FIFO)
methodology for storing the data items.
Non Linear Data Structures: This data structure does not form a sequence i.e. each item or element is connected with two
or more other items in a non-linear arrangement. The data elements are not arranged in sequential structure.
Non - Linear Data Structures: If a data structure organizes the data in random order, then that data structure is called as
Non-Linear Data Structure. Types of Non Linear Data Structures are given below:
Trees: Trees are multilevel data structures with a hierarchical relationship among its elements known as nodes. The
bottommost nodes in the hierarchy are called leaf node while the topmost node is called root node. Each node contains
pointers to point adjacent nodes.
Tree data structure is based on the parent-child relationship among the nodes. Each node in the tree can have more than
one children except the leaf nodes whereas each node can have utmost one parent except the root node. Trees can be
classified into many categories which will be discussed later in this tutorial.
Graphs: Graphs can be defined as the pictorial representation of the set of elements (represented by vertices) connected by
the links known as edges. A graph is different from tree in the sense that a graph can have cycle while the tree cannot have
the one.
ABSTRACT DATA TYPES:
The abstract data type is special kind of data type, whose behaviour is defined by a set of values and set of
operations.
The keyword “Abstract” is used as we can use these data types, we can perform different operations.
But how those operations are working that is totally hidden from the user.
The ADT is made of with primitive data types, but operation logics are hidden.
There are three types of ADTs:
1.Stack 2.Queue 3.List
LINKED LIST
The linked list is a linear data structure that contains a sequence of elements such that each element links to
its next element in the sequence.
Linked list is a dynamic data structure whose length can be increased or decreased at run time.
A linked list is used to store a collection of elements. Each element is stored in a linked list is called "Node".
data next
10 pointer
Node
Each “Node" contains two fields: Data field and Next field.
Next field is used to store the address of next node in the list.
ARRAY VS LINKED LIST:
ARRAY LINKED LIST
Size of an array is fixed Size of a list is not fixed
Memory is allocated from stack Memory is allocated from heap
It is necessary to specify the number of elements It is not necessary to specify the number of
during declaration (i.e., during compile time). elements during declaration (i.e., memory is
allocated during run time).
The insertion and deletion are done by moving The insertion and deletion are done by only
the elements either up or down. changing the pointers.
It occupies less memory than a linked list for the It occupies more memory.
same number of elements.
Inserting new elements at the front is potentially Inserting a new element at any position can be
expensive because existing elements need to be carried out easily.
shifted over to make room.
Deleting an element from an array is not possible. Deleting an element is possible.
1.0 Definition:
A data structure is basically a group of data elements that are put together under one name, and which defines a
particular way of storing and organizing data in a computer so that it can be used efficiently.
A data structure is a systematic way of organizing and accessing data.
The logical or mathematical model of a particular organization of data is called a Data structure.
Data structures are used in almost every program or software system. Some common examples of data structures are
arrays, linked lists, queues, stacks, binary trees, and hash tables.
1.1: Applications of Data Structures: Data structures are widely applied in the following areas:
Compiler design
Operating system
Statistical analysis package
DBMS
Numerical analysis
Simulation
Artificial intelligence
Graphic
1.2:Abstract Data Types(ADTs):
An abstract data type (ADT) is the way we look at a data structure, focusing on what it does and ignoring how it
does its job.
An ADT refers to a set of data values and associated operations that are specified accurately.
Data type:
Data type of a variable is the set of values that the variable can take. The basic data types in C include int, char,
float, and double.
Abstract:
The word ‘abstract’ in the context of data structures means considered apart from the detailed specifications or
implementation.
In C, an abstract data type can be a structure considered without regard to its implementation. It can be thought of
as a ‘description’ of the data in the structure with a list of operations that can be performed on the data within that
structure.
For example, when we use a stack or a queue, the user is concerned only with the type of data and the operations
that can be performed on it. Therefore, the fundamentals of how the data is stored should be invisible to the user.
They should not be concerned with how the methods work or what structures are being used to store the data.
They should just know that to work with stacks, they have push() and pop() functions available to them. Using
these functions, they can manipulate the data (insertion or deletion) stored in the stack.
Here, the size represents the memory taken by the primitive data types. For an instance, int takes 2 bytes, float takes 4
bytes of memory space in C programming.
We can understand it with the help of an example: Suppose an array, A [-10 ..... +2] having Base address (BA) = 999 and size
of an element = 2 bytes, find the location of A [-1].
L (A [-1]) = 999 + 2 x [(-1) - (-10)] = 999 + 18 = 1017.
Basic operations: Now, let's discuss the basic operations supported in the array –
• Traversal - This operation is used to print the elements of the array.
• Insertion - It is used to add an element at a particular index.
• Deletion - It is used to delete an element from a particular index.
• Search - It is used to search an element using the given index or by the value.
• Update - It updates an element at a particular index.
Array / List-based representation and operations:
Traversal operation: This operation is performed to traverse through the array elements. It prints all array elements one
after another. We can understand it with the below program:
void main() output:
{ Elements of the array:
int Arr[5] = {18, 30, 15, 70, 12}; Arr[0]=18,
int i; Arr[1]=30,
printf("Elements of the array are:\n"); Arr[2]=15,
for(i = 0; i<5; i++) Arr[3]=70,
{ Arr[4]=12,
printf("Arr[%d] = %d, ", i, Arr[i]);
}
}
Insertion operation: This operation is performed to insert one or more elements into the array. As per the requirements, an
element can be added at the beginning, end, or at any index of the array. Now, let's see the implementation of inserting an
element into the array.
int main() output:
{ Array elements before insertion:
int arr[20] = { 18, 30, 15, 70, 12 }; 18 30 15 70 12
int i, x, pos, n = 5; Array elements after insertion:
printf("Array elements before insertion:\n"); 18 30 15 50 70 12
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
x = 50; // element to be inserted
pos = 4;
n++;
for (i = n-1; i >= pos; i--)
arr[i] = arr[i - 1];
arr[pos - 1] = x;
printf("Array elements after insertion:\n");
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
return 0;
}
Deletion operation: As the name implies, this operation removes an element from the array and then reorganizes all of the
array elements.
void main() { output:
int arr[] = {18, 30, 15, 70, 12}; Given array elements are:
int k = 30, n = 5; arr[0]=18,
int i, j; arr[1]=30,
arr[2]=15,
printf("Given array elements are :\n");
arr[3]=70,
for(i = 0; i<n; i++) arr[4]=12,
{ Elements of array after deletion:
printf("arr[%d] = %d, ", i, arr[i]); arr[0]=18,
} arr[1]=30,
j = k; arr[2]=15,
arr[3]=70,
while( j < n)
{
arr[j-1] = arr[j];
j = j + 1;
}
n = n -1;
printf("\nElements of array after deletion:\n");
for(i = 0; i<n; i++)
{
printf("arr[%d] = %d, ", i, arr[i]);
}
}
Search operation: This operation is performed to search an element in the array based on the value or index.
void main() { output:
int arr[5] = {18, 30, 15, 70, 12}; Given array elements are:
int item = 70, i, j=0 ; arr[0]=18,
arr[1]=30,
printf("Given array elements are :\n");
arr[2]=15,
for(i = 0; i<5; i++) arr[3]=70,
{ arr[4]=12,
printf("arr[%d] = %d, ", i, arr[i]); Elements to be searched=70
} Element 70 is found at 4 position
printf("\nElement to be searched = %d", item);
while( j < 5)
{
if( arr[j] == item )
{
break;
}
j = j + 1;
}
printf("\nElement %d is found at %d position", item, j+1);
}
Update operation: This operation is performed to update an existing array element located at the given index.
void main() { output:
int arr[5] = {18, 30, 15, 70, 12}; Given array elements are:
int item = 50, i, pos = 3; arr[0]=18,
printf("Given array elements are :\n"); arr[1]=30,
for(i = 0; i<5; i++) arr[2]=15,
{ arr[3]=70,
printf("arr[%d] = %d, ", i, arr[i]); arr[4]=12,
} Array elements after updation:
arr[pos-1] = item; arr[0]=18,
printf("\nArray elements after updation :\n"); arr[1]=30,
for(i = 0; i<5; i++) arr[2]=50,
{ arr[3]=70,
printf("arr[%d] = %d, ", i, arr[i]); arr[4]=12,
}
}
The complexity of Array operations: Time and space complexity of various array operations are described in the following
table.
Time Complexity:
Operation Average Case Worst Case
Access O(1) O(1)
Search O(n) O(n)
Insertion O(n) O(n)
Deletion O(n) O(n)
1.4: Introducing Linked Lists: A linked list is a linear collection of data elements called nodes, which store a group of data
elements belonging to the same data type. Linked lists are also known as dynamic data structures. Unlike arrays, the data
elements of linked list are not stored at continuous memory locations. The elements are stored at a location, wherever the
elements find free memory space.
Unlike arrays, all the elements of a linked list need not be of the similar data types. For example, you can create a linked list,
which stores a group of characters, integers and floats.
A linked list is a data structure that contains that contains the data and the link field encapsulated in a node. In a linked list,
each node is divided into three parts-data, link and pointer. The data part stores the value of a data element, which is
stored in the node and the link stores the memory address of the next node. The pointer field is used to provide linear order
to the nodes. The syntax to declare a node in a linked list is:
struct node {
int data;
struct node *next;
};
The above syntax shows how to declare a node in a linked list. The keyword struct is used for defining a linked list. The data
variable holds the integer value stored in the node. The next field is a link that holds the address of the next node in the
linked list.
Operating Linked Lists:
You can perform various operations on a linked list such as creating and inserting a node in a linked list that contains
dissimilar data types. The following are the operations that you can perform on a linked list:
Creating, helps create the first node in a linked list.
Inserting, helps insert a node in the beginning, middle or end of a linked list
Deleting, help delete a node from a linked list.
Searching, helps find the location of a node in a linked list
Counting, help count the number of nodes in a linked list
Traversing, helps access the data of a node in a linked list
Categorizing Linked Lists:
You can use various types of linked list, which are:
Singly Linked List: Enables you to sequentially access the elements of the linked list in one direction. Singly linked
list is also called as the linear or one-way linked list.
Doubly linked list: Enables you to sequentially access the elements of the linked list in both directions, backward
and forward
Circular Linked List: Enables you to sequentially access the elements of the linked list in both directions in a cyclic
order.
Simple Linked Lists:
Single linked list is a sequence of elements in which every element has link to its next element in the sequence.
In any single linked list, the individual element is called as "Node". Every "Node" contains two fields, data field,
and the next field.
The data field is used to store actual value of the node and next field is used to store the address of next node in
the sequence.
In Single Linked List Navigation only forward direction.
Basic structure Node: Each node of a singly linked list follows a common basic structure.
struct node {
int data;
struct node *next;
};
struct node *head=NULL;
Step 2:If head=NULL,make newnod as head and head as temp(head=ptr and temp=head)
data next
10 NULL
head temp 1000
Program:
void create()
{
struct node *ptr;
int i,n,val;
printf("Enter Number of Elements\n");
scanf("%d",&n);
for(i=0;i<n;i++)
{
ptr=(struct node*)malloc(sizeof(struct node));
printf("Enter the data of node %d: ", i);
scanf("%d",&val);
ptr->data=val;
ptr->next=NULL;
if(head==NULL)
{
head=ptr;
temp=head;
}
else
{
temp->next=ptr;
temp=temp->next;
}
}
}
2. Insertion: In a single linked list, the insertion operation can be performed in three ways. They are as follows...
1. Inserting At Beginning of the list
2. Inserting At End of the list
3. Inserting At Specific location in the list
Inserting at Beginning of the list:
Program:
void insert_beg()
{
int num;
ptr=(struct node*)malloc(sizeof(struct node));
printf("Enter data:");
scanf("%d",&num);
ptr->data=num;
ptr->next=NULL;
if(head==NULL)
{
head=ptr;
}
else
{
ptr->next=head;
head=ptr;
}
}
Step 1 - Create a newNode with given value, Say “ ptr “ and ptr→ next as NULL.
Step 2 - Check whether list is Empty (head == NULL).
Step 3 - If it is Empty then, set head = ptr.
Step 4 - If it is Not Empty then, define a node pointer temp and initialize with head.
Step 5 - Keep moving the temp to its next node until it reaches to the last node in the list. (until temp → next is equal
to NULL).
Step 6 - Set temp → next = ptr.
Example:
Existing List with 10,20 and 30
data next data next data next
10 2000 20 3000 30 NULL
head 1000 2000 3000
Step 2:Make head as temp(temp=head) and traverse to the last node of the list(temp=temp->next)
data next data next data next data next
10 2000 20 3000 30 NULL 40 NULL
head 1000 2000 temp 3000 ptr 4000
Program:
void insert_end()
{
int num;
ptr=(struct node*)malloc(sizeof(struct node));
printf("Enter data:");
scanf("%d",&num);
ptr->data=num;
ptr->next=NULL;
if(head==NULL)
{
head=ptr;
}
else
{
temp=head;
while(temp->next!=NULL)
{
temp=temp->next;
}
temp->next=ptr;
}
}
Inserting At Specific location in the list (After a Node)
Program:
void delete_beg()
{
if(head==NULL)
{
printf("List is empty cant delete\n");
}
else
{
temp=head;
if(head->next == NULL)
{
head = NULL;
printf("Deleted element is %d",temp->data);
free(temp);
}
else
{
head=head->next;
printf("Deleted element is %d",temp->data);
free(temp);
}
}
}
Program:
void delete_end() {
if(head==NULL)
{
printf("Empty List cant delete\n");
}
else
{
temp=head;
if(head->next == NULL)
{
head = NULL;
printf("Deleted element is %d",temp->data);
free(temp);
}
else
{
while(temp->next!=NULL)
{
temp1=temp;
temp=temp->next;
}
temp1->next=NULL;
last=temp1;
printf("Deleted element is %d",temp->data);
free(temp);
}
}
}
Deleting a Specific Node from the list:
Step 1 - Check whether list is Empty (head == NULL)
Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and terminate the function.
Step 3 - If it is Not Empty then, define two Node pointers 'temp' and 't' and initialize 'temp' with head.
Step 4- Traverse the nth Node.
Step 5- Finally, Set t=temp->next; and temp->next=t->next; t->next=NULL. and Delete " t"
diagram:
Deleting at specific node
Program:
int delete_pos()
{
int pos,i=1;
if(head==NULL)
{
printf("List is empty!!");
return 0;
}
printf("Enter position to delete:");
scanf("%d",&pos);
temp=head;
while(i<pos-1)
{
temp=temp->next;
i++;
}
temp1=temp->next;
temp->next=temp1->next;
temp1->next=NULL;
printf("Deleted element is %d",temp1->data);
free(temp1);
return 0;
}
4. Displaying a Single Linked List
19
while (ptr!=NULL)
{
ptr = ptr -> next;
}
Algorithm
o STEP 1: SET PTR = HEAD
o STEP 2: IF PTR = NULL
WRITE "EMPTY LIST"
GOTO STEP 7
END OF IF
o STEP 4: REPEAT STEP 5 AND 6
UNTIL PTR != NULL
o STEP 5: PRINT PTR→ DATA
o STEP 6: PTR = PTR → NEXT
[END OF LOOP]
o STEP 7: EXIT
Here, 'link1' field is used to store the address of the previous node in the sequence, 'link2' field is used to store the address
of the next node in the sequence and 'data' field is used to store the actual value of that node.
Example:
void insert_end()
{
struct node *ptr; int num;
ptr=(struct node*)malloc(sizeof(struct node));
printf("Enter data:");
scanf("%d",&num);
ptr->data=num;
ptr->next=NULL;
if(head==NULL)
{
ptr->previous=NULL;
head=ptr;
}
else
{
struct Node *temp;
temp=head;
while(temp->next!=NULL)
{
temp=temp->next;
}
temp->next=ptr;
ptr->previous=temp;
}
}
Inserting At Specific location in the list (After a Node): We
can use the following steps to insert a new
node after a node in the double linked list...
Step 1 - Create a newNode with given value, Say “ ptr “.
Step 2 - Check whether list is Empty (head == NULL)
Step 3 - If it is Empty then, assign NULL to both ptr → previous & ptr → next and set ptr to head.
Step 4 - If it is not Empty then, define two node pointers temp1 & temp2 and initialize temp1 with head.
Step 5 - Assign temp1 → next to temp2, ptr to temp1 → next, temp1 to ptr → previous, temp2 to ptr → next and
ptr to temp2 → previous.
Program:
int insert_pos()
{
struct node *ptr;
int pos,i=1,num;
ptr=(struct node*)malloc(sizeof(struct node));
printf("Enter data:");
scanf("%d",&num);
ptr->data=num;
printf("Enter position to insert:");
scanf("%d",&pos);
if(head==NULL)
{
ptr->previous=NULL;
ptr->next=NULL;
head=ptr;
}
else
{
struct node *temp1,*temp2;
temp1=head;
while(i<pos-1)
{
temp1=temp1->next;
i++;
}
temp2=temp1->next;
temp1->next=ptr;
ptr->previous=temp1;
ptr->next=temp2;
temp2->previous=ptr;
return 0;
}
}
4.Deletion : In a double linked list, the deletion operation can be performed in three ways
1. Deleting from Beginning of the list
2. Deleting from End of the list
3. Deleting a Specific Node
Deleting from Beginning of the list: We can use the following steps to delete a node from beginning of the double
linked list...
Step 1 - Check whether list is Empty (head == NULL)
Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and terminate the function.
Step 3 - If it is not Empty then, define a Node pointer 'temp' and initialize with head.
Step 4 - Check whether list is having only one node (temp → previous is equal to temp → next).
Step 5 - If it is TRUE, then set head to NULL and delete temp (Setting Empty list conditions)
Step 6 - If it is FALSE, then assign temp → next to head, NULL to head → previous and delete temp.
Program:
void delete_beg()
{
if(head==NULL)
{
printf("List is Empty!!! Deletion is not possible\n");
}
else
{
struct node *temp;
temp=head;
if(temp->previous==temp->next)
{
head=NULL;
printf("Deleted element is %d",temp->data);
free(temp);
}
else
{
head =temp->next;
head->previous=NULL;
printf("Deleted element is %d",temp->data);
free(temp);
}
}
}
Deleting from End of the list: We can use the following steps to delete a node from end of the double linked list...
Step 1 - Check whether list is Empty (head == NULL)
Step 2 - If it is Empty, then display 'List is Empty!!! Deletion is not possible' and terminate the function.
Step 3 - If it is not Empty then, define a Node pointer 'temp' and initialize with head.
Step 4 - Check whether list has only one Node (temp → previous and temp → next both are NULL)
Step 5 - If it is TRUE, then assign NULL to head and delete temp. And terminate from the function. (Setting Empty list
condition)
Step 6 - If it is FALSE, then keep moving temp until it reaches to the last node in the list. (until temp → next is equal to
NULL)
Step 7 - Assign NULL to temp1 → next and delete temp.
Program:
void delete_end()
{
if(head==NULL)
{
printf("List is Empty!!! Deletion is not possible\n");
}
else
{
struct node *temp,*temp1; temp=head;
if(temp->previous==temp->next)
{
head=NULL;
printf("Deleted element is %d",temp->data);
free(temp);
}
else
{
while(temp->next!=NULL)
{
temp1=temp; temp=temp->next;
}
temp1->next=NULL;
printf("Deleted element is %d",temp->data);
free(temp);
}
}
}
Deleting a Specific Node from the list: We can use the following steps to delete a specific node from the double linked
list...
Step 1 - Check whether list is Empty (head == NULL)
Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and terminate the function.
Step 3 - If it is not Empty, then define a Node pointer 'temp' and initialize with head
Program:
int delete_pos()
{
int pos,i=1;
if(head==NULL)
{
printf("List is Empty!!! Deletion is not possible\n");
}
else
{
struct node *temp,*t;
temp=head;
printf("Enter position to delete:");
scanf("%d",&pos);
if(temp->previous==temp->next)
{
head=NULL;
printf("Deleted element is %d",temp->data);
free(temp);
}
else
{
while(i<pos-1)
{
temp=temp->next;
i++;
}
t=temp->next;
temp->next=t->next;
t->next=NULL;
t->previous=NULL;
temp->next->previous=temp;
printf("Deleted element is %d",t->data);
free(t);
}
}
return 0;
}
3. Displaying a Double Linked List: We can use the following steps to display the elements of a double
linked list...
Step 1 - Check whether list is Empty (head == NULL)
Step 2 - If it is Empty, then display 'List is Empty!!!' and terminate the function.
Step 3 - If it is not Empty, then define a Node pointer 'temp' and initialize with
head.
Step 4 - Keep displaying temp → data with an arrow (->) until temp reaches to the last node
Step 5 - Finally, display temp → data with arrow pointing to NULL.
Program:
void display()
{
if(head==NULL)
{
printf("List is Empty!!!\n");
}
else
{
struct Node *temp;
temp=head;
printf("The linked list is:\n");
while(temp!=NULL)
{
printf("%d->",temp->data);
temp=temp->next;
}
printf("NULL");
}
}
5. Searching:
1. Initialize a node pointer, temp=head.
2. Input element to search from user. Store it in some variable say "key".
3. Declare a variable to store index of found element through list, say "count=0".
4. Do following while temp is not NULL.
temp->data == key , if the condition is true, The element is found.
otherwise ,increment count ( count++) and move temp to its next node (temp = temp->next )
5. While temp is NULL, The element is not found.
Program:
int searchNode()
{
struct node *temp = head;
int key,count=0;
printf("\nEnter the element to be searched in the list : ");
scanf("%d",&key);
while(temp != NULL)
{
if(temp->data == key)
{
printf("\nElement %d found at position %d",key,count);
return 0;
}
else
{
count+=1;
temp = temp->next;
}
}
printf("\n Element %d is not found in the list\n",key);
return 0;
}
In single linked list, every node points to its next node in the sequence and the last node points NULL. But in circular
linked list, every node points to its next node in the sequence but the last node points to the first node in the list.
Operations of Circular Linked List :
1. Creation :it helps to create a new circular linked list
2.Insertion: it helps to insert a new node from a circular linked list
3.Deletion: It helps to delete a node from a circular linked list
4. Display (or) Traversing: It helps to visit all the nodes in a circular linked
list.
5.Searching: it helps to search a node in a circular linked list
program:
#include<stdio.h>
#include<stdlib.h>
struct node
{
struct node *prev;
struct node *next;
int data;
};
struct node *head;
void insertion_beginning();
void insertion_last();
void deletion_beginning();
void deletion_last();
void display();
void search();
void main ()
{
int choice =0;
while(choice != 9)
{
printf("\n*********Main Menu*********\n");
printf("\nChoose one option from the following list ...\n");
printf("\n===============================================\n");
printf("\n1.Insert in Beginning\n
2.Insert at last\n
3.Delete from Beginning\n
4.Delete from last\n
5.Search\n
6.Show\n
7.Exit\n");
printf("\nEnter your choice?\n");
scanf("\n%d",&choice);
switch(choice)
{
case 1: insertion_beginning();break;
case 2: insertion_last();break;
case 3: deletion_beginning();break;
case 4: deletion_last();break;
case 5: search();break;
case 6: display();break;
case 7: exit(0); break;
default: printf("Please enter valid choice..");
}
}
}
void insertion_beginning()
{
struct node *ptr,*temp;
int item;
ptr = (struct node *)malloc(sizeof(struct node));
if(ptr == NULL)
{
printf("\nOVERFLOW");
}
else
{
printf("\nEnter Item value");
scanf("%d",&item);
ptr->data=item;
if(head==NULL)
{
head = ptr;
ptr -> next = head;
ptr -> prev = head;
}
else
{
temp = head;
while(temp -> next != head)
{
temp = temp -> next;
}
temp -> next = ptr;
prev = temp;
head -> prev = ptr;
ptr -> next = head;
head = ptr;
}
printf("\nNode inserted\n");
}
}
void insertion_last()
{
struct node *ptr,*temp;
int item;
ptr = (struct node *) malloc(sizeof(struct node));
if(ptr == NULL)
{
printf("\nOVERFLOW");
}
else
{
printf("\nEnter value");
scanf("%d",&item);
ptr->data=item;
if(head == NULL)
{
head = ptr;
ptr -> next = head;
ptr -> prev = head;
}
else
{
temp = head;
while(temp->next !=head)
{
temp = temp->next;
}
temp->next = ptr;
ptr ->prev=temp;
head -> prev = ptr;
ptr -> next = head;
}
}
printf("\nnode inserted\n");
}
void deletion_beginning()
{
struct node *temp;
if(head == NULL)
{
printf("\n UNDERFLOW");
}
else if(head->next == head)
{
head = NULL;
free(head);
printf("\nnode deleted\n");
}
else
{
temp = head;
while(temp -> next != head)
{
temp = temp -> next;
}
temp -> next = head -> next;
head -> next -> prev = temp;
free(head);
head = temp -> next;
}
}
void deletion_last()
{
struct node *ptr;
if(head == NULL)
{
printf("\n UNDERFLOW");
}
else if(head->next == head)
{
head = NULL;
free(head);
printf("\nnode deleted\n");
}
else
{
ptr = head;
if(ptr->next != head)
{
ptr = ptr -> next;
}
ptr -> prev -> next = head;
head -> prev = ptr -> prev;
free(ptr);
printf("\nnode deleted\n");
}
}
void display()
{
struct node *ptr;
ptr=head;
if(head == NULL)
{
printf("\nnothing to print");
}
else
{
printf("\n printing values ... \n");
The Stack ADT: The Stack Model, Implementation of Stacks, Applications of Stack.
1.7: STACK ADT
Stack is a linear data structure.
Stack is a Collection of similar data items in which both insertion and deletion operations are performed based on
LIFO (Last In First Out) principle.
In stack, the insertion and deletion operations are performed at only one end called “top”.
That means, a new element is added at top of the stack and an element is removed from the top of the stack.
In a stack, the insertion operation is performed using a function called "push" and deletion operation is
performed using a function called "pop".
Operations on a Stack Stack Representation:
3 3 3 3 3
top-> 2 30 2 2 2 2
1 20 top-> 1 20 1 1 1
0 10 0 10 top-> 0 10 0 0
#include<stdio.h>
#include<conio.h>
#define SIZE 5
void push(int);
void pop();
void display();
int stack[SIZE], top = -1;
void main()
{
int value, choice;
clrscr();
while(1)
{
printf("\n\n***** MENU *****\n");
printf("1. Push\n2. Pop\n3. Display\n4. Exit");
printf("\nEnter your choice: ");
scanf("%d",&choice);
switch(choice)
{
case 1: printf("Enter the value to be insert: ");
scanf("%d",&value);
push(value);
break;
case 2: pop();
break;
case 3: display();
break;
case 4: exit(0);
default: printf("\nWrong selection!!! Try again!!!");
}
}
}
void push(int value)
{
if(top == SIZE-1)
printf("\nStack is Full!!! Insertion is not possible!!!");
else
{
top++;
stack[top] = value;
printf("\nInsertion success!!!");
}
}
void pop()
{
if(top == -1)
printf("\nStack is Empty!!! Deletion is not possible!!!");
else
{
printf("\nDeleted : %d", stack[top]);
top--;
}
}
void display()
{
if(top == -1)
printf("\nStack is Empty!!!");
else
{
int i;
printf("\nStack elements are:\n");
for(i=top; i>=0; i--)
printf("%d\n",stack[i]);
}
}
Application of stack:
1. Stack is used by compilers to check for balancing of parentheses, brackets and braces.
2. Stack is used to evaluate a postfix expression.
3. Stack is used to convert an infix expression into postfix/prefix form.
4. In recursion, all intermediate arguments and return values are stored on the processor’s stack.
5. During a function call the return address and arguments are pushed onto a stack and on return they are popped off.
STACK APPLICATIONS:
a) INFIX INTO POSTFIX :
#include<stdio.h>
#include<conio.h>
#define MAX 50
char stack[MAX];
int top=-1
void push(char); char pop();
int priority(char);
void main()
{
char a[MAX],ch; int i;
clrscr();
printf("Enter an infix expression:\t");
gets(a);
printf("\the postfix expression for the given expression is:\
t");
for(i=0;a[i]!='\0';i++)
{
ch=a[i];
if((ch>='a') && (ch<='z'))
printf("%c",ch);
else if(ch=='(') push(ch); else if(ch==')')
{
while((ch=pop())!='(')
printf("%c",ch);
}
else
{
while(priority(stack[top])>priority(ch))
printf("%c",pop());
push(ch);
}
}
while(top>-1)
printf("%c",pop());
printf("\n");
getch();
}
void push(char ch)
{
if(top==MAX-1)
{
printf("STACK OVERFLOW");
return;
}
else
{
top++;
stack[top]=ch; } }
char pop()
{
int x; if(top==-1)
{
printf("STACK EMPTY");
}
else
{
x=stack[top]; top--;
}
return x;
}
int priority(char ch)
{
switch(ch)
{
case '^': return 4; case '*':
case '/': return 3; case '+':
case '-': return 2; default : return 0;
}
}
OUTPUT:
Enter an infix expression:
((a + b ((b ^ c – d))) * (e – (a / c)))
The postfix expression for the given expression is:
a b b c ^ d - + e a c / - *
An expression is a collection of operators and operands that represents a specific value. An expression can be represented
in various forms such as
1. Infix Notation
5
operands value2=3
2. Prefix (Polish) Notation.
(5 + 3) = 8
3. Postfix (Reverese-Polish) Notation.
1. Infix Notation: if the operator is used in between the operands are called Infix Notation.
8
Syntax: <operand> <operator> <operand>
5 Example: a+ b 8 Push ( 8 ) (5 + 3) = 8
2. Prefix (Polish) Notation: If the operator is used before operands are called Prefix notation.
8
Syntax : <operator> <operand> <operand>
8
Example: + ab
63. Postfix (Reverse-Polish) Notation: If2 the operator is used after operands are called Postfix notation.
Push ( 2 ) 2 (5 + 3) = 8
Syntax : <operand> <operand><operator>
8
Example: ab+
8
Every expression can be represented using all the above three different types of expressions.
we can convert an expression from one form to another form like
7 1. Conversion of Infix expression to Postfix expression.
pop two
- val
2. Conversion of Infix expression to Prefix expression.operands ue
1= 6
3. Evolution of Postfix expression. 2 8
val
4. Balancing of Symbols Order of ue
2=
Precedence (Highest to Lowest)
8
Exponential ( ^ or ↑ ) – Highest precedence (8-
2)
Multiplication ( * or x ) or Division ( / or ÷ ) – Left to Right – Next precedence =6
8 pop two
Addition ( + ) or Subtraction ( *- ) – Left to Right - Lowest Precedenceoperands value1=6
1. Conversion of Infix expression to Postfix expression: Steps required for value2=8 conversion of Infix to
Postfix expression 48
(8 * 6)=48
1. Read an Expression from left to right.
2. If the character is LEFT PARANTHESIS, PUSH to the stack.
3. If the character is OPERAND, ADD Nill
to the postfix expression. Pop Stack is 48
9 4. If the character is OPERATOR, check whether stack is empty or not. elements Empty
5. from
a) If the stack is Empty, then push operator into the stack. stack.
b) If the stack is not Empty, check the priority of the operator
To evaluate a postfix expression using Stack data structure we can use the following steps...
i) If scan operator is higher priority than the top of stack operator then scanned operator will push into the stack.
ii) If scan operator is same or lower priority than the top of stack operator then pop the operator from the stack and
1. Read an Expression from left to right.
add to postfix expression and scanned operator will push into the stack, Repeat step 4.
2. If the character is OPERAND, then PUSH into stack.
6. If the character is RIGHT PARANTHESIS, then pop all the operators from the stack until it reaches LEFT
3. PARANTHESIS
If the character is OPERATOR, POP top two operands from the stack perform calculation and PUSH the result back
and ADD to postfix expression.
into stack.
7. After reading all characters, if stack is not empty then pop and ADD to postfix expression.
4.After reading the characters from the postfix expression stack will be having only the value which is result.
Example 1 : Convert A + B to postfix expression.
Example: Consider the postfix expression
S.No Scanned Operation Stack Postfix
Character 53+82-* Expression
1 A Add to postfix 'A' Stack is Empty A
The
2 Queue ADT:
+ Queue Model, Array
Pushimplementation
'+' of Queue, Application of Queues.
+ A
QUEUE ADT: B Add to postfix 'B' + AB
3
QueueNilldata structure is aPop
collection of similar data
all the operators from items in which insertion
the stack Stack and deletion operations
is Empty AB+ are performed
4 based on FIFO(First In First Out) principle.
and add to postfix expression
Example 2 : Convert A + ( B * C ) to postfix expression.
Queue is a linear data structure in which the insertion and deletion operations are performed at two different
ends.
The insertion is performed at one end called ‘rear’ and deletion is performed at another end called ‘front’.
Operations on a Queue
The following operations are performed on a queue data structure...
1. enQueue(value) - (To insert an element into the queue)
2. deQueue() - (To delete an element from the queue)
3. display() - (To display the elements of the queue)
Example
1) Initially front=rear=-1.It indicates Queue is empty 7) Delete(10 is removed)
0 1 2 3 0 1 2 3
20 30 40
front rear
2) Insert 10 0 1 2 3
10 8)Delete(20 is removed)
front rear 0 1 2 3
30 40
3) Insert 20 0 1 2 3 front rear
10 20
front rear 8)Delete(30 is removed)
0 1 2 3
4) Insert 30 0 1 2 3 40
10 20 30 front rear
front rear
9)Delete(40 is removed)
5) Inser 40 0 1 2 3 0 1 2 3
10 20 30 40
front rear front= rear=-1
QUEUE IMPLEMENTATION: Queue data structure can be implemented in two ways. They are as follows...
1. Queue using Array
2. Queue using Linked List
void push(int);
void pop();
void display();
void main()
{
int choice, value;
clrscr();
printf("\n:: Stack using Linked List ::\n");
while(1)
{
printf("\n****** MENU ******\n");
printf("1. Push\n2. Pop\n3. Display\n4. Exit\n");
printf("Enter your choice: ");
scanf("%d",&choice);
switch(choice)
{
case 1: printf("Enter the value to be insert: ");
scanf("%d", &value);
push(value);
break;
case 2: pop(); break;
case 3: display(); break;
case 4: exit(0);
default: printf("\nWrong selection!!! Please try again!!!\n");
}
}
}
void push(int value)
{
struct node *ptr;
ptr = (struct node*)malloc(sizeof(struct node));
ptr->data = value;
if(top == NULL)
ptr->next = NULL;
else
ptr->next = top;
top = ptr;
}
void pop()
{
if(top == NULL)
printf("\nStack is Empty!!!\n");
else
{
struct node *temp = top;
printf("\nDeleted element: %d", temp->data);
top = temp->next;
free(temp);
}
}
void display()
{
if(top == NULL)
printf("\nStack is Empty!!!\n");
else
{
struct node *temp = top;
while(temp->next != NULL)
{
printf("%d--->",temp->data);
temp = temp -> next;
}
printf("%d--->NULL",temp->data);
}
}
In above example, the last inserted node is 50 and it is pointed by 'rear' and the first inserted node is 10 and it is
pointed by 'front'.
The order of elements inserted is 10, 15, 22 and 50.
Queue Operations: To implement queue using linked list, we need to set the
following things before implementing actual operations.
Step 1 - Include all the header files which are used in the program. And declare all the user defined functions.
Step 2 - Define a 'Node' structure with two members data and next.
Step 3 - Define two Node pointers 'front' and 'rear' and set both to NULL.
Step 4 - Implement the main method by displaying Menu of list of operations and make suitable function calls in
the main method to perform user selected operation.
1. enQueue(value) - Inserting an element into the Queue: We can use the following steps to insert a n ew node into
the queue...
Step 1 - Create a newNode say ‘ptr’ with given value and set 'ptr → next' to NULL.
Step 2 - Check whether queue is Empty (rear == NULL)
Step 3 - If it is Empty then, set front = ptr and rear = rear.
Step 4 - If it is Not Empty then, set rear → next = ptr and rear = ptr.
program:
void delete()
{
if(front == NULL)
printf("\nQueue is Empty!!!\n");
else
{
struct node *temp = front;
front = front -> next;
printf("\nDeleted element: %d\n", temp->data);
free(temp);
}
}
3. display() - Displaying the elements of Queue: We can use the following steps to display the elements (nodes) of a
queue...
Step 1 - Check whether queue is Empty (front == NULL).
Step 2 - If it is Empty then, display 'Queue is Empty!!!' and terminate the function.
Step 3 - If it is Not Empty then, define a Node pointer 'temp' and initialize with front.
Step 4 - Display 'temp → data --->' and move it to the next node. Repeat the same until 'temp' reaches to 'rear' (temp
→ next! = NULL).
Step 5 - Finally! Display 'temp → data ---> NULL'.
program:
void display()
{
if(front == NULL)
printf("\nQueue is Empty!!!\n");
else
{
struct Node *temp = front;
while(temp->next != NULL)
{
printf("%d--->",temp->data);
temp = temp -> next;
}
printf("%d--->NULL\n",temp->data);
}
}
Implementation of Queue Datastructure using Linked List
#include<stdio.h>
#include<conio.h>
struct node
{
int data;
struct node *next;
}*front = NULL,*rear = NULL;
void insert(int);
void delete();
void display();
void main()
{
int choice, value;
clrscr();
printf("\n:: Queue Implementation using Linked List ::\n");
while(1)
{
printf("\n****** MENU ******\n");
printf("1. Insert\n2. Delete\n3. Display\n4. Exit\n");
printf("Enter your choice: ");
scanf("%d",&choice);
switch(choice)
{
case 1: printf("Enter the value to be insert: ");
scanf("%d", &value);
insert(value);
break;
case 2: delete(); break;
case 3: display(); break;
case 4: exit(0);
default: printf("\nWrong selection!!! Please try again!!!\n");
}
}
}
void insert(int value)
{
struct node *ptr;
ptr = (struct node*)malloc(sizeof(struct node));
ptr->data = value;
ptr -> next = NULL;
if(front == NULL)
front = rear = ptr;
else
{
rear -> next = ptr;
rear = ptr;
}
}
void delete()
{
if(front == NULL)
printf("\nQueue is Empty!!!\n");
else
{
struct node *temp = front;
front = front -> next;
printf("\nDeleted element: %d\n", temp->data);
free(temp);
}
}
void display()
{
if(front == NULL)
printf("\nQueue is Empty!!!\n");
else
{
struct node *temp = front;
while(temp->next != NULL)
{
printf("%d--->",temp->data);
temp = temp -> next;
}
printf("%d--->NULL\n", temp->data);
}
}
Applications of Queue:
1. It is used to schedule the jobs to be processed by the CPU.
2. When multiple users send print jobs to a printer, each printing job is kept in the printing queue. Then the printer prints
those jobs according to first in first out (FIFO) basis.
3. Breadth first search uses a queue data structure to find an element from a graph.
1. Difference between stacks and Queues?
stacks Queues
1. A stack is a linear list of elements in which the element 1. A Queue is a linear list of elements in which the
may be inserted or deleted at one end. elements are added at one end and deletes the elements
at another end.
2. In stacks, elements which are inserted last is the first 2. In Queue the element which is inserted first is the
element to be deleted. element deleted first.
3.Stacks are called LIFO (Last In First Out) list 3. Queues are called FIFO (First In First Out) list.
4. In stack elements are removed in reverse order in which 4. In Queue elements are removed in the same order in
thy are inserted. which thy are inserted.
5.suppose the elements a,b,c,d,e are inserted in the stack, 5. Suppose the elements a,b,c,d,e are inserted in the
the deletion of elements will be e,d,c,b,a. Queue, the deletion of elements will be in the same order
in which thy are inserted.
6. In stack there is only one pointer to insert and delete 6. In Queue there are two pointers one for insertion called
called “Top”. “Rear” and another for deletion called “Front”.
7. Initially top=-1 indicates a stack is empty. 7. Initially Rear=Front=-1 indicates a Queue is empty.
8. Stack is full represented by the condition TOP=MAX-1(if 8. Queue is full represented by the condition Rear=Max-1.
array index starts from ‘0’).
9.To push an element into a stack, Top is incremented by 9. To insert an element into Queue, Rear is incremented by
one one.
10. To POP an element from stack, top is decremented by 10.To delete an element from Queue, Front is incremented
one. by one
11.The conceptual view of Stack is as follows: 11.The conceptual view of Queue is as follows:
UNIT-2: Searching:
List Searches:
Searching techniques are used to retrieve a particular record from a list of records in an efficient manner so that the
least possible tome is consumed. The list of records can have a key field, which can be used to identify a record. Therefore,
the given value must be matched with the key value in order to find a particular record. If the searching technique identifies
a particular record then the search operation is said to be successful otherwise it is said to be unsuccessful. The techniques,
which are used to search data from memory of computer, are called internal searching techniques. The techniques, which
are used to search data from a storage device such as hard disk, are called external searching techniques.
Generally, there are two types of searching techniques, which can be used to locate a particular record in the given list of
records. These techniques are:
Linear search
Binary search
Linear search: Linear search, also known as sequential search, involves searching a data item in a given set of data items.
These data items are stored in structures such as arrays. Each data item is checked one by one, in the record in which it
exists in the structure, to determine if it matches the criteria of search.
The steps used in the implementation of Linear Search are listed as follows -
• First, we have to traverse the array elements using a for loop.
• In each iteration of for loop, compare the search element with the current array element, and -
If the element matches, then return the index of the corresponding array element.
If the element does not match, then move to the next element.
• If there is no match or the search element is not present in the given array, return -1.
Linear Search Algorithm:
Linear_Search(a, n, val) // 'a' is the given array, 'n' is the size of given array, 'val' is the value to search
Step 1: set pos = -1
Step 2: set i = 1
Step 3: repeat step 4 while i <= n
Step 4: if a[i] == val
set pos = i
print pos
go to step 6
[end of if]
set ii = i + 1
[end of loop]
Step 5: if pos = -1
print "value is not present in the array "
[end of if]
Step 6: exit
Working of Linear search: Now, let's see the working of the linear search Algorithm.
To understand the working of linear search algorithm, let's take an unsorted array. It will be easy to understand the working
of linear search with an example.
Let the elements of array are :
Now, the element to be searched is found. So, algorithm will return the index of the element matched.
Linear Search complexity: Now, let's see the time complexity of linear search in the best case, average case, and worst case.
We will also see the space complexity of linear search.
1. Time Complexity
Case Time Complexity
Best Case O(1)
Average Case O(n)
Worst Case O(n)
• Best Case Complexity - In Linear search, best case occurs when the element we are finding is at the first position of
the array. The best-case time complexity of linear search is O(1).
• Average Case Complexity - The average case time complexity of linear search is O(n).
• Worst Case Complexity - In Linear search, the worst case occurs when the element we are looking is present at the
end of the array. The worst-case in linear search could be when the target element is not present in the given
array, and we have to traverse the entire array. The worst-case time complexity of linear search is O(n).
The time complexity of linear search is O(n) because every element in the array is compared only once.
2. Space Complexity
Space Complexity O(1)
Implementation of Linear Search: Now, let's see the programs of linear search in different programming languages.
Program: Write a program to implement linear search in C language
#include<stdio.h> output:
#include<conio.h> Enter the array elements
void main() 12 15 45 65 23
{ Enter the element to be searched
int k,a[5]; 65
int i=0,j; The element is present in the list
clrscr();
printf("Enter the array elements");
for(j=0;j<5;j++)
{
scanf("%d",&a[j]);
}
printf("Enter the element to be searched");
scanf("%d",&k);
while(i<5)
{
if(k==a[i])
break;
else
i=i+1;
}
if(i<5)
printf("The element is present in the list ");
else
printf("The element is not present in the
list");
getch();
}
Binary Search: Binary Search is a searching algorithm used in a sorted array by repeatedly dividing the search interval in
half. The idea of binary search is to use the information that the array is sorted and reduce the time complexity to O(Log n).
Sorting: Sorting techniques can be applied on a list of data so that the list can be analysed easily for making accurate
decisions. This becomes possible because sorting arranges the data in a predetermined order. For example, proper
sequence of allotting the house number in a sector makes you easily identify the house because the house numbers are
arranged in an arranged in an increasing order. You can arrange the data using various sorting techniques, which are as
follows:
Selection Sort: Selection sort is a technique in which the smallest element of an array is searched and swapped with the first
element of an array. Then, the second element is swapped with the next smallest element and this process continues till the
array is sorted. The first pass compares n-1 comparisons, the second pass compares n-2 comparisons and the third pass
compares n-3 comparisons. The total number of comparisons of the selection sort technique is:
(n-1)+(n-2)+(n-3)+………+1=n*n(n-1)/2
The complexity of the selection sort is O(n²), where n is the number of data items stored in an array. For example, an array,
num, has five data items and you have to sort these data items by using the selection sort technique. The data items stored
in an array, num, are:
num={55, 67, 21, 89, 16}
In the num array, the smallest data item, 16, replaces the first data item, 55, then the second smallest data item, 21,
replaces the second data item 67 and this continues until all the data items are stored. The steps involved in sorting the
num array are:
1. (55), 67, 21, 89, (16)
2. 16, (67), (21), 89, 55
3. 16, 21, (67), 89, (55)
4. 16, 21, 55, (89), (67)
Finally, the sorted array is 16, 21, 55, 67, 87.
Consider a program code that shows the selection sort technique to sort an array: There are two functions. sort()
and display(), to sort an array and display the sorted array, respectively. In the sort() function, the min variable
stores the index of the smallest element of an array and swaps the first element with the value of the smallest
element.
#include<stdio.h>
#include<conio.h>
void sort(int []); /* function prototype */
void dispaly(int []); /* function prototype */
void main()
{
int num[5],ctr;
clrscr();
printf("Enter the five numbers\n");
for(ctr=0;ctr<5;ctr++)
scanf("%d",&num[ctr]);
/*Acceptiong five numbers*/
sort(num); /*calls the sort() function*/
display(num); /*calls the display() function*/
getch();
}
void sort(int num[])
/* the sort() function to arrange the elements of an array*/
{
int i,j;
int temp;
int min;
for(i=0;i<4;i++)
{
min=i;
for(j=i+1;j<5;j++)
{
if ( num[j]<num[min])
{
min=j; /*locate the index of the smallest element*/
}
}
temp=num[min];
/*swaps the smallest element of an array*/
num[i]=num[min];
num[min]=temp;
}
}
void display(int num[])
/* The function to display*/
{
int a; /* the stored array*/
printf("\n Sorted Array");
for(a=0;a<5;a++)
printf("%d\n",num[a]);
}
Insertion Sort:
• Insertion sort is a sorting algorithm that places an unsorted element at its suitable place in each iteration.
• Insertion sort works similarly to we sort cards in our hands in a card game.
• We assume that the first card is already sorted then, we select an unsorted card. If the unsorted card is greater
than the card in hand, it is placed on the right otherwise, to the left. In the same way, other unsorted cards are
taken and put in their right place.
• A similar approach is used by insertion sort.
Characteristics of Insertion Sort:
• This algorithm is one of the simplest algorithms with simple implementation
• Basically, Insertion sort is efficient for small data values.
Insertion sort is adaptive in nature, i.e. it is appropriate for data sets that are already partially sorted
How Does Insertion Sort Work?
Suppose we need to sort the following array
1. Assume to store:
The first element in the array is assumed to be sorted. Take
the second element and store it separately in key Compare
the key with the first element. If the first element is
greater than the key, then the key is placed in front of the
first element.
program:
// Insertion sort in C
void printArray(int array[], int size) // Function to print an array
{
for (int i = 0; i < size; i++)
{
printf("%d ", array[i]);
}
printf("\n");
}
void insertionSort(int array[], int size)
{
for (int step = 1; step < size; step++)
{
int key = array[step];
int j = step - 1;
// Compare key with each element on the left of it until an element smaller than it is found.
// For descending order, change key<array[j] to key>array[j].
while (key < array[j] && j >= 0)
{
array[j + 1] = array[j];
--j;
}
array[j + 1] = key;
}
}
// Driver code
int main()
{
int data[] = {9, 5, 1, 4, 3};
int size = sizeof(data) / sizeof(data[0]);
insertionSort(data, size);
printf("Sorted array in ascending order:\n");
printArray(data, size);
}
Advantages of Insertion Sort:
It is simple sorting algorithm, in which the elements are sorted by considering one item at a time. The implementation
is simple.
It is efficient for smaller data set and for data set that has been substantially sorted before. It does not change the
relative order of elements with equal keys
It reduces unnecessary travels through the array
It requires constant amount of extra memory space.
Disadvantages:-
It is less efficient on list containing more number of elements.
As the number of elements increases the performance of program would be slow
Complexity of Insertion Sort:
BEST CASE:- Only one comparison is made in each pass. The Time complexity is O(n2 ).
WORST CASE:- In the worst case i.e; if the list is arranged in descending order, the number of comparisons required by
the insertion sort is given by:
1+2+3+………………………. + (n-2)+(n-1)= (n*(n-1))/2; = (n² -n)/2.
The number of Comparisons are O(n² ).
AVERAGE CASE:- In average case the number of comparisons is given by 1 2 + 2 2 + 3 3 + ⋯ + (n−2) 2 + (n−1) 2 = n∗(n−1)
2∗2 =( n² -n)/4 = O(n² ).
Quick Sort:
#include<stdio.h> OUTPUT:
#include<conio.h> Enter how many elements 5
void quick(int a[10],intlb,int n); Enter the elements 65 23 89 68 71
void main() The sorted elements are 23 65 68 71 89
{
intn,i,a[10];
clrscr();
printf("enter how many elements \n");
scanf("%d",&n);
printf("enter the elements \n");
for(i=0;i<n;i++) scanf("%d",&a[i]);
quick(a,0,n-1);
printf("the sorted elements are \n");
for(i=0;i<n;i++)
printf("%d \n",a[i]);
getch();
}
void quick(int a[],intlb,intub)
{
inti,j,t,key;
if(lb>ub) return;
i=lb;
j=ub;
key=lb;
while(i<j)
{
while(a[key]>a[i])
i++;
while(a[key]<a[j])
j--;
if(i<j)
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
t=a[j];
a[j]=a[key];
a[key]=t;
quick(a,0,j-1);
quick(a,j+1,ub);
}
Advantages of Quick Sort:
This is fastest sorting technique among all.
It efficiency is also relatively good.
It requires small amount of memory
Disadvantages:
It is somewhat complex method for sorting.
It is little hard to implement than other sorting methods
It does not perform well in the case of small group of elements.
Complexities of Quick Sort:
Average Case: The running time complexity is O(n log n).
Worst Case: Input array is not evenly divided. So the running time complexity is O(n2 ).
Best Case: Input array is evenly divided. So the running time complexity is O(n logn).
Merge Sort: The merge sort technique combines two sorted array into one larger sorted array. For example, The sorted
array, A, contains p elements and the sorted array, B contains q elements. The merge sort technique combines the elements
of A and B into a single sorted array, C with p+q elements.
The total number of comparisons in the merge sort technique to sort n data-items of an array is log n. The merge sort
technique requires at most log n passes, so the complexity of the merge sort is O(n log n) . For example, to merge the two
sorted arrays into a single sorted array by using the merge sort technique, the data items sorted in an array. A are:
A={56, 78}
The data items stored in an array, B , are:
B={45, 67, 89}
The data items of the C array after merging the two sorted arrays, A and B, are:
C={45, 56, 67, 78, 89}
The first data item of the A array is compared with the first data item of the B array. If the first data item of A is smallest
than the first data item of B, then that data item from A is removed to the new array, C. If the data item of B is smaller then
the data item of A, then it is moved to the array, C. This comparing of data items continues until one of the arrays ends.
Consider the following program code that shows how to use the selection sort technique to sort an array:
#include<stdio.h>
#include<conio.h>
int j,a[15],i,temp,n;
void main()
{
void createheap(int)
clrscr();
printf("Enter number of elements\n");
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=n;i>=2;i--)
createheap(i);
for(i=n-1;i>=1;i--)
{
temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
for(j=1;j>=2;j--)
createheap(j);
}
printf("The sorted elements are:");
for(i=1;i<=n;i++)
printf("%d",a[i]);
getch();
}
void createheap(int y)
{
if(y>1)
{
if(a[y]>a[y/2])
{
temp=a[y];
a[y]=a[y/2];
a[y/2]=temp;
createheap(y/2);
}
}
}
Advantages:
Merge sort is stable sort
It is easy to understand
It gives better performance.
Disadvantages:
It requires extra memory space
Copy of elements to temporary array
It requires additional array
It is slow process.
Complexity of Merge Sort: The merge sort algorithm passes over the entire list and requires at most log n passes and
merges n elements in each pass. The total number of comparisons required by the merge sort is given by O(n log n).
External searching: When the records are stored in disk, tape, any secondary storage then that searching is known as
‘External Searching’. Internal Searching: When the records are to be searched or stored entirely within the computer
memory then it is known as ‘Internal Searching’.
Heap Sort:
#include<stdio.h> OUTPUT:
#include<conio.h> Enter the size of array: 4
void maxheap(int [],int,int); Enter the elements of array: 35 21 95
void buildmaxheap(int a[],int n) 17
{ Sorted array is: 17 21 35 95
int i;
for(i=n/2;i>=1;i--)
{
maxheap(a,i,n);
}
}
void maxheap(int a[],inti,int n)
{
int R,L,largest,t;
L=2*i;
R=2*i+1;
if((L<=n) && (a[L]>a[i]))
largest=L;
else largest=i;
if((R<=n) && (a[i]>a[largest]))
largest=R;
if(largest!=i)
{
t=a[i];
a[i]=a[largest];
a[largest]=t;
maxheap(a,largest,n);
}
}
void heapsort(int a[],int n)
{
int i,temp;
buildmaxheap(a,n);
for(i=n;i>=2;i--)
{
temp=a[1];
a[1]=a[i];
a[i]=temp;
maxheap(a,1,i-1);
}
}
vod main()
{
int a[50],i,n;
clrscr();
printf("Enter the size of array : ");
scanf("%d",&n);
printf("Enter the elements of array \n");
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
heapsort(a,n);
printf("sorted array is \n");
for(i=1;i<=n;i++)
{
printf("%d\t", a[i]);
}
getch();
}
Hashing: Hashing is a searching technique that depends on the number of elements in a set of data. You need to compute
the location of record such that you can retrieve the record in a single access. The location of the record such that you can
retrieve the record in a single access. The location of the desired record is present in the search table that depends on the
given key but not on other keys. For example, a company assigned a 4-digitemployee code to its 100 employees that will be
used as a primary key in the employee’s file of the company. You can use the employee code as the address of the record in
the memory. No two employees will have the same employee code. But this method will need space for more than 12,000
memory locations.
You can use the idea of using the given key to determine the address of a record. But you need to make changes in this ides
so that a lot of space is not wasted. The changes made by you take the form of a function H from the set K of keys in the set
L of memory address. This will lead to the generation of the following function
H: K->L
The above function is hash function or hashing function. But, this function will not give distinct values of hash as it is
possible that two different keys K1 and K2 will provide the same hash address. This is termed as collision of the following of
two parts:
Hash function
Collision resolution.
Hash Function:
Hashing(Hash Technique)
Hashing is a technique to convert a range of key values into a range of indexes of an array
Use modulo operator to get a range of key values.
Hash Function:
The fixed process to convert a key to a hash key is known as a hash function.
This function will be used whenever access to the table is needed.
One common method of determining a hash key is the division method of hashing.
The formula that will be used is:
Hash key = key % table size
Example:
Assume a table size is 8.Put the values in the Hash table {36,18,72,43,6)
Collision Resolution-Separate Chaining.
Collision: If the hash function returns same hash key for more than one element then this situation is called Collision.
(OR)
If x1 and x2 are two different keys, but the hash values of x1 and x2 are equal (i.e, h(x1) =h(x2)) then it is called as a
Collision.
Example: {131,3,4,21,61,24,7,97,89},Table size=10
0 H(131)=131%10=1
1 131
2 H(3)=3%10=3
3 3
4 4 H(4)=4%10=4
5
6 H(21)=21%10=1
7 97 Collision
8 H(61)=61%10=1
9 89
H(24)=24%10=4
H(7)=7%10=7
H(97)=97%10=7
H(89)=89%10=9
Collision Resolution Techniques: Collision Resolution Techniques are the techniques used for resolving or handling the
collision. Collision resolution techniques are classified as
Separate Chaining
Problem: Using the hash function ‘key mod 7’, insert the following sequence of keys in the hash table- 50, 700, 76, 85, 92,
73 and 101. Use separate chaining technique for collision resolution.
Solution: The given sequence of keys will be inserted in the hash table as-
Step-1:
Draw an empty hash table.
For the given hash function, the possible range of hash values is [0, 6].
So, draw an empty hash table consisting of 7 buckets as
Step-2:
Insert the given keys in the hash table one by one.
The first key to be inserted in the hash table = 50.
Bucket of the hash table to which key 50 maps = 50 mod 7 = 1.
So, key 50 will be inserted in bucket-1 of the hash table as
Step-3:
The next key to be inserted in the hash table = 700.
Bucket of the hash table to which key 700 maps = 700 mod 7 = 0.
So, key 700 will be inserted in bucket-0 of the hash table as
Step-4:
The next key to be inserted in the hash table = 76.
Bucket of the hash table to which key 76 maps = 76 mod 7 = 6.
So, key 76 will be inserted in bucket-6 of the hash table as
Step-5:
The next key to be inserted in the hash table = 85.
Bucket of the hash table to which key 85 maps = 85 mod 7 = 1.
Since bucket-1 is already occupied, so collision occurs.
Separate chaining handles the collision by creating a linked list to
bucket-1.
So, key 85 will be inserted in bucket-1 of the hash table as
Step-6:
The next key to be inserted in the hash table = 92.
Bucket of the hash table to which key 92 maps =
92 mod 7 = 1.
Since bucket-1 is already occupied, so collision
occurs.
Separate chaining handles the collision by creating
a linked list to bucket-1.
So, key 92 will be inserted in bucket-1 of the hash
table as
Step-7:
Step-8:
The next key to be inserted in the hash table =
101.
Bucket of the hash table to which key 101 maps =
101 mod 7 = 3.
Since bucket-3 is already occupied, so collision
occurs.
Separate chaining handles the collision by creating
a linked list to bucket-3.
So, key 101 will be inserted in bucket-3 of the
hash table as
Open Addressing:
In open addressing,
Unlike separate chaining, all the keys are stored inside the hash table.
No key is stored outside the hash table.
Techniques used for open addressing are:
1. Linear Probing 2. Quadratic Probing 3.Double Hashing
Operations in Open Addressing
Let us discuss how operations are performed in open addressing
Insert Operation
Hash function is used to compute the hash value for a key to be inserted.
Hash value is then used as an index to store the key in the hash table.
In case of collision,
Probing is performed until an empty bucket is found.
Once an empty bucket is found, the key is inserted.
Probing is performed in accordance with the technique used for open addressing.
Search Operation: To search any particular key,
Its hash value is obtained using the hash function used.
Using the hash value, that bucket of the hash table is checked.
If the required key is found, the key is searched.
Otherwise, the subsequent buckets are checked until the required key or an empty bucket is found.
The empty bucket indicates that the key is not present in the hash table.
Delete Operation
The key is first searched and then deleted.
After deleting the key, that particular bucket is marked as “deleted”.
1. Linear Probing: In linear probing,
When collision occurs, we linearly probe for the next bucket.
We keep probing until an empty bucket is found.
Advantage:
It is easy to compute.
Disadvantage:
The main problem with linear probing is clustering.
Many consecutive elements form groups.
Then, it takes time to search an element or to find an empty bucket.
Problem: Using the hash function ‘key mod 7’, insert the following sequence of keys in the hash table- 50, 700, 76, 85, 92,
73 and 101.Use linear probing technique for collision resolution.
Solution: The given sequence of keys will be inserted in the hash table
Step-01:
Draw an empty hash table.
For the given hash function, the possible range of hash values is [0, 6].
So, draw an empty hash table consisting of 7 buckets as
Step-02:
Insert the given keys in the hash table one by one.
The first key to be inserted in the hash table = 50.
Bucket of the hash table to which key 50 maps = 50 mod 7 = 1.
So, key 50 will be inserted in bucket-1 of the hash table as
Step-03:
The next key to be inserted in the hash table = 700.
Bucket of the hash table to which key 700 maps = 700 mod 7 = 0.
So, key 700 will be inserted in bucket-0 of the hash table as
Step-04:
The next key to be inserted in the hash table = 76.
Bucket of the hash table to which key 76 maps = 76 mod 7 = 6.
So, key 76 will be inserted in bucket-6 of the hash table as
Step-05:
The next key to be inserted in the hash table = 85.
Bucket of the hash table to which key 85 maps = 85 mod 7 = 1.
Since bucket-1 is already occupied, so collision occurs.
To handle the collision, linear probing technique keeps probing linearly until an empty
bucket is found.
The first empty bucket is bucket-2.
So, key 85 will be inserted in bucket-2 of the hash table as
Step-06:
The next key to be inserted in the hash table = 92.
Bucket of the hash table to which key 92 maps = 92 mod 7 = 1.
Since bucket-1 is already occupied, so collision occurs.
To handle the collision, linear probing technique keeps probing linearly until an empty
bucket is found.
The first empty bucket is bucket-3.
So, key 92 will be inserted in bucket-3 of the hash table as
Step-07:
The next key to be inserted in the hash table = 73.
Bucket of the hash table to which key 73 maps = 73 mod 7 = 3.
Since bucket-3 is already occupied, so collision occurs.
To handle the collision, linear probing technique keeps probing linearly until an empty
bucket is found.
The first empty bucket is bucket-4.
So, key 73 will be inserted in bucket-4 of the hash table as
Step-08:
The next key to be inserted in the hash table = 101.
Bucket of the hash table to which key 101 maps = 101 mod 7 = 3.
Since bucket-3 is already occupied, so collision occurs.
To handle the collision, linear probing technique keeps probing linearly until an empty
bucket is found.
The first empty bucket is bucket-5.
So, key 101 will be inserted in bucket-5 of the hash table as
2.Quadratic Probing:
In quadratic probing,
When collision occurs, we probe for i2‘th bucket in ith iteration.
We keep probing until an empty bucket is found.
3.Double Hashing:
Example:
Load Factor (α):
Load factor (α) is defined as
UNIT-3: Trees: Binary Trees-Implementation, Expression Trees. Binary Search Trees-find, findMin and findMax, insert,
delete operations.UNIT-3: Trees:
Tree: A tree is a non-linear hierarchical data structure that consists of nodes connected by edges.
OR
A tree is a connected graph without any circuits.
If in a graph, there is one and only one path between every pair of vertices, then graph is called as a tree.
Why Tree Data Structure?
Other data structures such as arrays, linked list, stack, and queue are linear data structures that store data
sequentially.
In order to perform any operation in a linear data structure, the time complexity increases with the increase in the
data size. But, it is not acceptable in today's computational world.
Different tree data structures allow quicker and easier access to the data as it is a non-linear data structure.
Example:
Properties:
The important properties of tree data structure are-
There is one and only one path between every pair of vertices in a tree.
A tree with n vertices has exactly (n-1) edges.
A graph is a tree if and only if it is minimally connected.
Any connected graph with n vertices and (n-1) edges is a tree.
Tree Terminology
1. Root
The first node from where the tree originates is called as Example:
a root node.
In any tree, there must be only one root node.
We can never have multiple root nodes in a tree data
structure.
2. Edge
The connecting link between any two nodes is called as Example:
an edge.
In a tree with n number of nodes, there are exactly (n-1)
numbers of edges.
3. Parent
The node which has a Example: Here,
branch from it to any other Node A is the parent of
node is called as a parent node. nodes B and C
In other words, the node Node B is the parent of
which has one or more children nodes D, E and F
is called as a parent node. Node C is the parent of
In a tree, a parent node can nodes G and H
have any number of child nodes. Node E is the parent of
nodes I and J
Node G is the parent of
node K
4. Child
The node which is a Example Here,
descendant of some node Nodes B and C are the
is called as a child node. children of node A
All the nodes except Nodes D, E and F are
root node are child nodes. the children of node B
Nodes G and H are
the children of node C
Nodes I and J are the
children of node E
Node K is the child of
node G
5. Siblings
Example Here,
Nodes B and C are siblings
Nodes which belong to Nodes D, E and F are
the same parent are called siblings
as siblings. Nodes G and H are siblings
In other words, nodes Nodes I and J are siblings
with the same parent are sibling
nodes.
6. Degree
8. Leaf Node
The node which does not Example: Here, nodes D, I, J, F, K and H are
have any child is called as a leaf leaf nodes.
node.
Leaf nodes are also called
as external nodes or terminal
nodes.
9. Level
In a tree, each step from top to bottom is called Example
as level of a tree.
The level count starts with 0 and increments by 1
at each level or step.
10. Height
Total number of edges that lies Example Here,
on the longest path from any Height of node A = 3
leaf node to a particular node is Height of node B = 2
called as height of that node. Height of node C = 2
Height of a tree is the height Height of node D = 0
of root node. Height of node E = 1
Height of all leaf nodes = 0 Height of node F = 0
Height of node G = 1
Height of node H = 0
Height of node I = 0
Height of node J = 0
Height of node K = 0
11. Depth
Total number of edges Example: Here,
from root node to a Depth of node A = 0
particular node is called Depth of node B = 1
as depth of that node. Depth of node C = 1
Depth of a tree is the Depth of node D = 2
total number of edges Depth of node E = 2
from root node to a leaf Depth of node F = 2
node in the longest path. Depth of node G = 2
Depth of the root node = Depth of node H = 2
0 Depth of node I = 3
The terms “level” and Depth of node J = 3
“depth” are used Depth of node K = 3
interchangeably.
12. Subtree
In a tree, each child from a node forms Example:
a subtree recursively.
Every child node forms a subtree on its parent
node.
Types of Trees:
1. Binary Tree 2. Binary Search Tree 3.AVL Tree 4.Red-Black Tress 5.Splay Tree
Binary Trees-Implementation:
1.Binary Tree
Tree is a non-linear data structure.
Example:
In a tree data structure, a node can have any number of child
nodes.
Binary tree is a special tree data structure in which each node
can have at most 2 children.
Thus, in a binary tree, Each node has either 0 child or 1 child
or 2 children.
One is known as a left child and the other is known as right
child.
Expression Tree: Binary trees are widely used to store algebraic expressions.
For example, consider the algebraic expression given as:
Exp = (a – b) + (c * d)
This expression can be represented using a binary tree as shown in Fig
Binary Search Tree is a special kind of binary tree in which nodes are arranged in a specific order.
In a binary search tree (BST), each node contains-
Only smaller values in its left sub tree
Only larger values in its right sub tree
Example: The following tree is a Binary Search Tree. In this tree, left subtree of every node contains nodes with smaller
values and right subtree of every node contains larger values.
Note:
Every binary search tree is a binary tree but every binary tree need not to be binary search tree.
All the values in a BST must be distinct
find, findMin and findMax
Operations on a Binary Search Tree
The following operations are performed on a binary search tree...
1. Insertion 2.Search 3.Deletion
Insertion Operation in BST: In binary search tree, new node is always inserted as a leaf node.
The insertion operation is performed as follows...
Step 1 - Create a newNode with given value and set its left and right to NULL.
Step 2 - Check whether tree is Empty.
Step 3 - If the tree is Empty, then set root to newNode.
Step 4 - If the tree is Not Empty, then check whether the value of newNode is smaller or larger than the node (here it
is root node).
Step 5 - If newNode is smaller than or equal to the node then move to its left child. If newNode is larger than the node
then move to its right child.
Step 6- Repeat the above steps until we reach to the leaf node (i.e., reaches to NULL).
Step 7 - After reaching the leaf node, insert the newNode as left child if the newNode is smaller or equal to that leaf
node or else insert it as right child.
Example: Construct a Binary Search Tree (BST) for the following sequence of numbers- 50, 70, 60, 20, 90, 10, 40, 100
Solution:
When elements are given in a sequence,
Always consider the first element as the root node.
Consider the given elements and insert them in the BST one by one.
The binary search tree will be constructed as explained below:
Insert 50
inserting
Insert 70
As 70 > 50, so insert 70 to the right of 50.
Insert 60
As 60 > 50, so insert 60 to the right of 50.
As 60 < 70, so insert 60 to the left of 70.
Insert 20
As 20 < 50, so insert 20 to the left of 50
Insert 90
As 90 > 50, so insert 90 to the right of 50.
As 90 > 70, so insert 90 to the right of 70.
Insert 10
As 10 < 50, so insert 10 to the left of 50.
As 10 < 20, so insert 10 to the left of 20.
Insert 40
As 40 < 50, so insert 40 to the left of 50.
As 40 > 20, so insert 40 to the right of 20.
Insert 100
As 100 > 50, so insert 100 to the right of 50.
As 100 > 70, so insert 100 to the right of 70.
As 100 > 90, so insert 100 to the right of 90.
Consider the following example where node with value = 20 is deleted from the BST-
Case 3: Deleting a node with two children: We use the following steps to delete a node with two children from
BST...
Step 1 - Find the node to be deleted using search operation
Step 2 - If it has two children, then find the largest node in its left subtree (OR) the smallest node in its right subtree.
Step 3 - Swap both deleting node and node which is found in the above step.
Step 4 - Then check whether deleting node came to case 1 or case 2 or else goto step 2
Step 5 - If it comes to case 1, then delete using case 1 logic.
Step 6- If it comes to case 2, then delete using case 2 logic.
Step 7 - Repeat the same process until the node is deleted from the tree.
Example: A node with two children may be deleted from the BST in the following two ways-
Method-1:
Method-2:
Visit to the left subtree of the deleting node.
Pluck the greatest value element called as inorder predecessor.
Replace the deleting element with its inorder predecessor.
Example
Consider the following example where node with value = 15 is deleted from the BST
Tree Traversal
Tree Traversal refers to the process of visiting each node in a tree data structure exactly once.
Various tree traversal techniques are
1. Preorder Traversal
Algorithm:
1. Visit the root
2. Traverse the left sub tree i.e. call Preorder (left sub tree)
3. Traverse the right sub tree i.e. call Preorder (right sub tree)
Root → Left → Right
Example
Consider the following example
2. Inorder Traversal
Algorithm
1. Traverse the left sub tree i.e. call Inorder (left sub tree)
2. Visit the root
3. Traverse the right sub tree i.e. call Inorder (right sub tree)
3. Postorder Traversal
Algorithm
1. Traverse the left sub tree i.e. call Postorder (left sub tree)
2. Traverse the right sub tree i.e. call Postorder (right sub tree)
3. Visit the root
Left → Right → Root
Example
Consider the following example
Breadth First Traversal
Breadth First Traversal of a tree prints all the nodes of a tree level by level.
Breadth First Traversal is also called as Level Order Traversal.
Example
Example: Make a BST for the following sequence of numbers: 45, 36, 76, 23, 89, 115, 98, 39, 41, 56, 69, 48
Traverse the tree in Preorder, Inorder and postorder.
Ans: A binary search tree B is a binary tree each node of which satisfies the following conditions:
1. The value of the left-subtree of ‘x’ is less than the value at ‘x’
2. The value of the right-subtree of ‘x’ is greater than value at ‘x’
3. the left-subtree and right-subtree of binary search tree are again binary search tree.
Output:
Inorder traversal
5 ->12 ->6 ->1 ->9 ->
Preorder traversal
1 ->12 ->5 ->6 ->9 ->
Postorder traversal
5 ->6 ->12 ->9 ->1 ->
UNIT-4: Trees:
AVL Trees-Single and Double Rotation, Operations.
AVL TREE (Adelson, Velski & Landis): An AVL tree is a self balancing Binary Search Tree(BST). In an AVL tree, balance factor
of every node is either -1, 0 or +1.
Balance Factor: Balance factor of a node in an AVL tree is the difference between the height of the left subtree
and the height of the right subtree of that node.
Balance Factor = Height of Left Subtree - Height of Right Subtree
The above tree is a binary search tree and every node is satisfying balance factor condition. So this tree is said to be an AVL
tree.
Note: Every AVL Tree is a binary search tree but every Binary Search Tree need not be AVL tree.
AVL Rotations
If the difference in the height of left and right sub-trees is more than 1, the tree is balanced using some rotation
techniques
Rotation is the process of moving nodes either to left or to right to make the tree balanced.
There are four rotations and they are classified into two types.
Left Rotation (LL Rotation)
In LL Rotation, every node moves one position to left from the current position. To understand LL Rotation, let us consider
the following insertion operation in AVL Tree.
Single Right Rotation (RR Rotation): In RR Rotation, every node moves one position to right from the current position. To
understand RR Rotation, let us consider the following insertion operation in AVL Tree.
LR Rotation is a sequence of single left rotation followed by a single right rotation. In LR Rotation, at first, every node moves
one position to the left and one position to right from the current position. To understand LR Rotation, let us consider the
following insertion operation in AVL Tree...
Tree is Balanced
Insert 20
As 20 < 50, so insert 20 in 50’s left sub tree. 1
5o
0
20
Tree is Balanced
Insert 60
As 60 > 50, so insert 60 in 50’s right sub tree. 0
50
0 0
20 60
Tree is Balanced
Insert 10
50
20
As 10 < 50, so insert 10 in 50’s left sub tree. 1
As 10 < 20, so insert 10 in 20’s left sub tree.
50
1 0
20 60
0
10
Tree is Balanced
Insert 8
2
As 8 < 50, so insert 8 in 50’s left sub tree.
50
As 8 < 20, so insert 8 in 20’s left sub tree.
As 8 < 10, so insert 8 in 10’s left sub tree.
2 0
20 60
1
10
Tree is Imbalanced
0
8
50 50
2 0 0 0
20 60 10 60
RR Rotation
1 0 0
10 8 20
Tree is Imbalanced Tree is balanced
0
8
continues
As 15 < 50, so insert 15 in 50’s left sub tree. 2
0 15
Tree is Imbalanced
Step-07: Insert 32 10
As 32 > 20, so insert 32 in 20’s right sub tree. 0
As 32 < 50, so insert 32 in 50’s left sub tree. 20
8 2
0 1 0
10 50
0 0 0 0
8 15 32 60
15
Tree is Balanced
Step-08: Insert 46
-1
As 46 > 20, so insert 46 in 20’s right sub tree.
20
As 46 < 50, so insert 46 in 50’s left sub tree. 50
0 1 1
As 46 > 32, so insert 46 in 32’s right sub tree. 1020 50
0 0 -1 0
8 15 32 60
10 50 0
46 20 60
Tree is Balanced
8 15 32 60
Step-09: Insert 11 20 10
As 11 < 20, so insert 11 in 20’s left sub tree. 46
0
Tree is Balanced
Step-10: Insert 48
-1
As 48 > 20, so insert 48 in 20’s right sub tree.
20
20
As 48 < 50, so insert 48 in 50’s left sub tree.
-1 2
As 48 > 32, so insert 48 in 32’s right sub tree.
10 10 50 50
As 48 > 46, so insert 48 in 46’s right sub tree.
0 1 -2 0
8 15 32 60
8 15 32 60
0 1
11 11 46 46
0
48
0 Tree is balanced
Tree is Imbalanced 48
Step 1:
The node to be deleted from the tree is 8. 0
15
If we observe it is the parent node of the
0 0
node 5 and 9.
Since the node 8 has two children it can be 12 54
0 -1 1 0
replaced by either of it’s child nodes. 8 13 18 60
0 0 0 0 0 0
5 9 14 16 56 70
Step 2:
The node 8 is deleted from the tree. 0
As the node is deleted we replace it with either of 15
it’s children nodes. 0 0
Here we replaced the node with the inorder 12 54
successor, i.e, 9. 1 -1 1 0
Again we check the balance factor for each node. 9 13 18 60
0 0 0 0 0
5 14 16 56 70
Step 3:
Now The next element to be deleted is 12. 0
If we observe, we can see that the node 12 has a 15
left subtree and a right subtree. 0 0
We again can replace the node by either it’s 12 54
inorder successor or inorder predecessor. 1 -1 1 0
In this case we have replaced it by the inorder 9 13 18 60
successor. 0 0 0 0 0
5 14 16 56 70
Step 4:
The node 12 is deleted from the tree. 0
Since we have replaced the node with the inorder 15
successor, the tree structure looks like shown in 1 0
the image. 13 54
After removal and replacing check for the balance 1 0 1 0
factor of each node of the tree. 9 14 18 60
0 0 0 0
5 16 56 70
Step 5:
The next node to be eliminated is 14. 0
15
It can be seen clearly in the image that 14 is a leaf 1 0
node. 13 54
Thus it can be eliminated easily from the tree. 1 0 1 0
9 14 18 60
0 0 0 0
5 16 56 70
Step 6:
As the node 14 is deleted, we check the balance 0
factor of all the nodes. 15
We can see the balance factor of the node 13 is 2. 2 0
This violates the terms of the AVL tree thus we 13 54
need to balance it using the rotation mechanism. 1 1 0
9 18 60
0 0 0 0
5 16 56 70
Step 7:
In order to balance the tree, we identify the 0
rotation mechanism to be applied. 15
Here we need to use RR Rotation. 2 0
The nodes involved in the rotation is shown as 13 54
follows. 1 1 0
9 18 60
0 0 0 0
5 16 56 70
Step 8:
The nodes are rotated and the tree satisfies the -1
conditions of an AVL tree. 15
The final structure of the tree is shown as follows. 0 0
We can see all the nodes have their balance factor 9 54
as ‘0’ , ‘1’ and ‘-1’. 0 0 1 0
5 13 18 60
0 0 0
16 56 70
Search Opearation of AVL Tree: The search operation of an AVL tree is same as search operation of Binary Search Tree.
B-Tree: A B-tree is a balanced multiway search tree. A multiway search tree of order m is the tree in which each node can
have a maximum of m child nodes. The maximum number of keys for a node in a multiway tree is one less than the
maximum number of child nodes it can have. Therefore, a node with m child nodes can have k=m-1 keys.
A B-tree has certain properties that make it a balanced multiway search tree.
These properties that make it a balanced multiway search tree.
These properties are:
Leaf nodes are on the same level
All nodes can have a maximum of m child nodes and a minimum of m/2 child nodes. However, the root node is an
exception to this criterion as it may have less than m/2 child nodes.
The number of keys in each internal node, non-root and non-leaf node, is one less than the number of child nodes.
The fig shows a multiway search tree order 4 in which some of the nodes are empty.
The following code defines the values 5 for the MAX variable and 2 for the MIN variable, representing that the
maximum number of nodes of the of the B-tree is 5 and the minimum number of nodes of the B-tree is 2:
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#define max 5/* A B-tree of oreder 6*/
#define MIN 2
The following code defines search() function, which enables you to search the position of a node in the B-tree:
struct Bnode* serach(int data,struct Bnode* root, int* index)
{
struct Bnode* n=root;
if(root==NULL)
return NULL;
*index=0;
if(data >= n->data[1])
{
*index=n->children;
while((data< n->data[*index]) && *index>1)
(*index)--;
if(data == n->data[*index])
return root;
}
return search(data,root->child[*index],index);
}
The following code defines the del() function, which enables you to delete a node from the B-tree:
void del(int data)
{
struct Bnode* temp;
if(!delhelp(data,root))
{
printf("\n Value %d not found",data);
return;
}
if(root->children==0)
{
temp=root;
root=root->child[0];
free(temp);
}
}
UNIT-5: Trees:
Introduction to Red-black:
Red - Black Tree Data structure:
Red Black Tree is a Binary Search Tree in which every node is colored either RED or BLACK.
In Red Black Tree, the color of a node is decided based on the properties of Red-Black Tree. Every Red Black Tree
has the following properties.
Example:
The above tree is a Red-Black tree where every node is satisfying all the properties of Red-Black Tree.
Note: Every Red Black Tree is a binary search tree but every Binary Search Tree need not be Red Black tree.
Example: Create a RED BLACK Tree by inserting following sequence of elements 8,18,5,15,17,25,40 & 80
Insert 8
Tree is empty. So insert newNode as Root node with Red
color. Root-Black
8 8
If Root node is Red, color(Root) is changed to black and exit
from the operation.
Insert 18
Tree is not empty. So insert newNode with red color. 5
8
18
Insert 5
Tree is not empty. So insert newNode with red color.
8
5 18
Insert 15
Tree is not empty. So insert newNode with red color.
8
5 18
15
8
8
8 Root-Black
5 8 5 1
18
5 18
15 15
15
After RECOLOR operation, the tree is satisfying all RED BLACK Tree properties.
Insert 17
Tree is not empty. So insert newNode with red color.
8
Here there are two consecutive Red nodes(18 & 15).
5 8
18
15
17
8 8 8
5 8 5 8 5 8
18 18 17
Left Rotation Recolor Right Rotation
17 17 15 18
15 15
Insert 25
Tree is not empty. So insert newNode with red color.
8
5 8
17
15 18
25
5 8
17
After RECOLOR
15 18
25
After RECOLOR operation, the tree is satisfying all RED BLACK Tree properties.
Insert 40
Tree is not empty. So insert newNode with red color. 8
5 8
17
15 18
25
40
8
5 8 17
Recolor
18 5 8 17
15
Left Rotation
25 15 25
40 18 40
After LL Rotation & Recolor operation, the tree is satisfying all RED BLACK Tree properties.
Insert 80
Tree is not empty. So insert newNode with red color.
8
5 8
17
15 25
18 40
80
5 8
17
After Recolor
15 25
18 40
80
After Recolor again there are two consecutive Red nodes(17 & 25).
The newNode’s parent sibling color is black. And nodes are same side.
We use Recolor and Left Rotation then Recheck.
8
17
5 8
17
Recolor
8 25
8
15 25
Left Rotation 15
5 15 18 40
15
18 40
80 80
Finally above Tree is satisfying all the Properties of RED BLACK Tree and it is perfect RED BLACK Tree.
Splay trees :
Splay tree is another variant of a binary search tree. In a splay tree, recently accessed element is placed at the root
of the tree.
In a splay tree, every operation is performed at the root of the tree. All the operations in splay tree are involved
with a common operation called "Splaying"
Splaying an element is the process of bringing it to the root position by performing suitable rotation operations.
Every operation on splay tree performs the splaying operation.
For example, the insertion operation first inserts the new element using the binary search tree insertion process,
then the newly inserted element is splayed so that it is placed at the root of the tree.
The search operation in a splay tree is nothing but searching the element using binary search process and then
splaying that searched element so that it is placed at the root of the tree.
Rotations in Splay Tree
1. Zig Rotation
2. Zag Rotation
3. Zig - Zig Rotation
4. Zag - Zag Rotation
5. Zig - Zag Rotation
6. Zag - Zig Rotation
Example: Insert 0,2,1,6,4,5 into Splay trees
1. Zag Rotation 1 Insert 0,2
p x
2
0
x 2 0 p
3.Zag-Zag Rotation
3 Insert 6
g p
1 1 2 x 2
1 2 6
p 0 g2 x 1 6
0 2 1 0 6 2 2 p
1
x
0 1 1
6 0 6 g 0
6
0 0
4.Zig-Zag Rotation
4 Insert 4 6 6
g g 6 6
6 6 4
6 x
2 4
2
p 4
2 4 2
x
4 2
1 4 p g
x 1 4 2 2 6
1 4 p 2 1
0 2 1 4
0 1 1
0 1 0
1 0
0
0
0
1
0
0
5.Zag-Zig Rotation
5 Insert 5
g g x
4 4 5
p p g p
2 6 2 5 4 6
x x
1 5 1 6 2
0 0 1
Binary Search Tree O(log n) O(log n) O(log n) Binary Search Tree O(n) O(n) O(n)
AVL tree O(log2 n) O(log2 n) O(log2 n) AVL tree O(log2 n) O(log2 n) O(log2 n)
Red-Black Tree O(log n) O(log n) O(log n) Red-Black Tree O(log n) O(log n) O(log n)
Splay Tree O(log2 n) O(log2 n) O(log2 n) Splay Tree O(log2 n) O(log2 n) O(log2 n)
Priority Queues:
A priority queue contains a set of data elements in which each element is assigned a pre-defined priority. Priority is defined
as a numeric value, which is assigned on the basis of time a data element is inserted in the priority queue. Unlike a circular
queue, a priority queue does not work on the FIFO technique.
You can insert or delete a data element in a priority queue on priority basis. You need to process the data elements of
higher priority before the elements of lower priority. You need to process the elements of the same priority in the order the
elements are inserted in the queue.
You can implement two types of priority queue-ascending and descending. In an ascending priority queue, you can insert
data elements randomly but a data elements with the lowest priority is removed first. However, in a descending priority
queue, you can insert the data elements randomly but a data element with the highest priority is removed first from the
queue. You can implement a priority quesue using linked list as well as arrays.
Consider the following program code to show how to implement an ascending priority queue using arrays. It
includes the operations of priority queue such as insert and removal
#define true 1
#define false 0
#include<conio.h>
#include<conio.h>
#include<process.h>
struct PQueue
{
int arr[20];
int number;
}pq;
void Initialize()
{
pq.number=0;
}
void add_element(int);
int empty();
int remove_element();
int empty()
{
if(pq.number==0)
return (1);
return (0);
}
void add_element(int data)
{
int j;
if(empty()==true)
{
pq.arr[pq.number++]=data;
}
else
{
for(j=pq.number-1;j>=0;j--)
{
if(data>pq.arr[j])
pq.arr[j+1]=pq.arr[j];
else
break;
}
pq.arr[j+1]=data;
pq.number++;
}
}
int remove_element()
{
if(empty==false)
return pq.arr[--pq.number];
printf("\n\tPriority Queue is empty");
return -9999;
}
void main()
{
int element,d;
char ch;
clrscr();
Initialize();
while(1)
{
clrscr|();
printf("\n\tImplementing Asci9nding Priority Queue");
printf("\n\t1.Insert an element:");
printf("\n\t2.Remove an element:");
printf("\n\t3.Exit from the program");
printf("\n\tEnter your choice");
fflush(stdin);
scanf("%c",&ch);
switch(ch-'0')
{
case 1:printf("\n\tEnter an element to be inserted into the priority
queue:");
scanf("%d",&element);
add_element(element);
getch();
break;
case 2:d=remove_element();
printf("\n\tThe removed element is:%d",d);
getch();
break;
case 3:
exit();
break;
default:
printf("\n\tInvalid choice. Please reenter");
break;
}/*Ending with switch case*/
}/*Ending with while loop*/
}
output:
Implementing Ascinding Priority Queue
1.Insert an element:
2.Remove an element:
3.Exit from the program
Enter your choice:1
Enter an element to be inserted into the priority queue:30
UNIT-I
1. a) Write a program to reverse the given single linked list with starting node as ‘head’. [7M]
b) What are the operations of stack? List its applications in computer science. [7M]
2.
a) Write a program to implement stack using linked list. [7M]
b) How can we find the address of a second node from the end in a single linked list? Write pseudo code for it.
[7M]
UNIT-II
3. a) Write a program to implement selection sort. [7M]
b) Write a program to find maximum element in a binary tree. [7M]
4. a) Write a program to implement binary search. [7M]
b) What is Hash function? What are its types? How can we handle the collision using separate chaining and
analyze its performance? [7M]
UNIT-III
5.a) Write a program to insert an element into a Binary search tree. [7M]
b) What is an expression tree? Explain evaluation of an expression tree with an example. [7M]
6. a) Compare full and complete binary trees with examples. [7M]
b) Explain how can we delete a node with both the children from a binary search tree? Give an example. [7M]
UNIT-IV
7. a) Construct an AVL Tree with the following elements and determine the number of levels in the
constructed tree. 25, 21, 32, 37, 45, 5, 9, 15, 84, 7, 91, 3, 6, 41, 1 [7M]
b) Define B-Tree of order 5. Explain insertion procedure in B-tree of order 5. [7M]
8. a) Define AVL Tree. What are types of rotations performed while inserting an element into an AVL tree?
[7M]
b) Construct a B-Tree of order 5 with the following elements. 52, 85, 94, 65, 74, 84, 37, 15, 19, 21, 62, 77, 99,
101, 137
UNIT-V
9. a) Explain how can we find maximum element in the minimum heap? Write a pseudo code for it. [7M]
b) What is a Splay tree? How it is different from binary search tree? [7M]
10. a) Compare the implementation of search operation in binary search, AVL and red black trees. [7M]
b) How to perform insertion and deletion in Priority Queue implemented using min-heap? Explain with
suitable examples. [7M]
UNIT-I
1. a) Write a program to implement queue using linked list. [7M]
b) Explain how can we find the number of nodes in a single linked list? Write a pseudo code for it. [7M]
2. a) What are the operations of Queue? List its applications in computer science. Write a program. [7M]
b) Write a program to implement single linked list with starting node as ‘head’. [7M]
UNIT-II
3. a) Write a program to implement insertion sort. [7M]
b) Write the algorithm to illustrate the merge operation of the sorted lists of elements. [7M]
4. a) Write a program to implement linear search. [7M]
b) What is a collision? How can we use separate chaining for the collision resolution? [7M]
UNIT-III
5. a) Write a program to search for an element in a Binary search tree. [7M]
b) Write a pseudo code to check whether the given binary search tree is balanced or not. [7M]
6. a) What is a complete binary tree? Draw and determine number of levels of a complete binary tree with 14
nodes. [7M]
b) Construct a binary search tree with the following elements and determine its height. 15, 84, 7, 91, 3, 6, 41,
1, 25, 21, 32, 37, 45, 5, 9 [7M]
UNIT-IV
7. a) Construct an AVL Tree with the following elements and determine its height. 45, 5, 9, 15, 84, 7, 91, 3, 6,
41, 25, 21, 32, 37, 1 [7M]
b) Construct a B-Tree of order 5 with the following elements. 52, 85, 94, 65, 74, 84, 37, 15, 19, 21, 62, 77, 99,
101, 137 [7M]
8. a) Define AVL Tree. What are types of rotations performed while inserting an element into an AVL tree?
[7M]
b) Define B-Tree of order 7. Explain deletion procedure in B-tree of order 7 with examples.
9. a) How can we find minimum element in the maximum heap? Explain. [7M]
b) How to perform insertion and deletion in Priority Queue? Explain with suitable examples. [7M]
10. a) Write the implementation of search operation in red black trees.. [7M]
b) What is a Splay tree? How it is different from binary search tree? List any two applications of splay trees.
UNIT-I
1. a) Write a program to insert an element into a single linked list by considering all the possible cases. [7M]
b) What is a stack? Explain how it can be useful in evaluating expressions with suitable examples. [7M]
2. a) Write a program to implement stack using arrays. [7M]
b) Write a program to insert, delete and print the elements using doubly linked list. [7M]
UNIT-II
3. a) Write a program to implement quick sort. [7M]
b) Derive the time complexity of quick sort in best, worst and average cases. [7M]
4. a) What is a binary search? Explain how the number 41 can be searched in the list containing 11, 15, 20, 24,
27,29, 37, 41, 45, 51, 65, 66, 67, 78, 81, 84, 87, 91. [7M]
b) What is Hash function? What are its types? How can we handle the collision using separate chaining and
analyze its performance? [7M]
UNIT-III
5. a) Write a procedure to find total number of nodes in a binary tree. [7M]
b) Write a program to perform insertion into a Binary search tree. [7M]
6. a) Explain how a node with both the children can be deleted from a binary search tree with suitable
examples. [7M]
b) Compare full and complete binary tree with examples. [7M]
UNIT-IV
7. a) Construct an AVL Tree with the following elements 45, 5, 9, 15, 84, 7, 91, 6, 41, 1, 25, 21, 32, 37, 3 [7M]
b) Define B-Tree of order 7. Explain deletion procedure in B-tree of order 7. [7M]
8. a) Define AVL Tree. What are double rotations performed while inserting an element into an AVL tree? [7M]
b) Construct a B-Tree of order 5 with the following elements. 37, 15, 19, 21, 62, 77, 99, 52, 85, 94, 65, 74, 84,
121 [7M]
UNIT-V
9. a) How can we find second minimum element in the minimum heap? [7M]
b) What is a Splay tree? How it is different from binary search tree? [7M]
10.a) Compare Binary search trees and Red-black trees? [7M]
b) Explain how to perform insertion and deletion in Priority Queue implemented using max-heap? Explain with
suitable examples.
UNIT-I
1. a) Write a program to implement queue using arrays. [7M]
b) Explain how to find whether the single linked list contains a loop? Write a pseudo code for it. Assume the
single linked list is having initial node as ‘head’. [7M]
2. a) What are the operations of Circular linked list? List its applications in computer science. [7M]
b) Write a program to reverse the given single linked list with starting node as ‘head’. [7M]
UNIT-II
3. a) Write a program to implement heap sort. [7M]
b) Derive the time complexity of quick sort in best, worst and average cases. Give examples for each case. [7M]
4. a) Compare linear search and binary search. [7M]
b) What is a collision? How can we use separate chaining for the collision resolution? [7M]
UNIT-III
5. a) Write a program to perform search in a Binary search tree. [7M]
b) Derive the maximum number of comparisons performed to search for an element in a binary search tree
with n*2n nodes. [7M]
6. a) What is a complete binary tree? Draw and Determine number of levels of a complete binary tree with 14
nodes. [7M]
b) Construct a binary search tree with the following elements 45, 5, 9, 3, 6, 41, 1, 25, 21, 32, 15, 84, 7, 91, 37.
[7M]
UNIT-IV
7. a) Construct an AVL tree with the following elements and determine the height of the constructed tree 6,
41, 25, 21, 32, 37, 1, 45, 5, 9, 15, 84, 7, 91, 3. [7M]
b) Define B-Tree of order 5. Explain insertion procedure in B-tree of order 5 with examples. [7M]
8. a) Define AVL Tree. Prove that the height of the AVL tree with n nodes is O(logn). [7M]
b) Construct a B-Tree of order 5 with the following elements and determine the height of the constructed tree
219, 221, 162, 177, 299, 101, 137, 152, 185, 94, 165, 74, 284, 137, 115.
UNIT-V
9. a) Explain how can we find second maximum element in the maximum heap? Write pseudo code for it. [7M]
b) Describe how to perform insertion and deletion in Priority Queue? Explain with suitable examples. [7M]
10. a) In which context AVL trees out perform Red-black trees? Justify. [7M]
b) What is a Splay tree? How it is different from binary search tree? List any two applications of splay trees.