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

Data Structure-ECE NOTES

This document outlines a course on data structures. The course objectives are to solve problems using linear data structures like lists, stacks and queues, and advanced structures like balanced search trees. The course outcomes are for students to select appropriate data structures for problems, implement sorting and searching techniques, and demonstrate operations on binary search trees and advanced structures like AVL trees and B-trees. The course contains 5 units covering topics like linear and linked lists, stacks, queues, searching, sorting, hashing, trees, and priority queues.

Uploaded by

apparisanjay403
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
521 views

Data Structure-ECE NOTES

This document outlines a course on data structures. The course objectives are to solve problems using linear data structures like lists, stacks and queues, and advanced structures like balanced search trees. The course outcomes are for students to select appropriate data structures for problems, implement sorting and searching techniques, and demonstrate operations on binary search trees and advanced structures like AVL trees and B-trees. The course contains 5 units covering topics like linear and linked lists, stacks, queues, searching, sorting, hashing, trees, and priority queues.

Uploaded by

apparisanjay403
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 102

Course Code: Data Structures L T P c

(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.

 Data field is used to store actual value of the node

 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.

Advantage of using ADTs:


In the real world, programs evolve as a result of new
requirements or constraints, so a modification to a
program commonly requires a change in one or more of
its data structures.
For example, if you want to add a new field to a student’s
record to keep track of more information about each
student, then it will be better to replace an array with a
linked structure to improve the program’s efficiency. In
such a scenario, rewriting every procedure that uses the
changed structure is not desirable. Therefore, a better
alternative is to separate the use of a data structure from
the details of its implementation. This is the principle
underlying the use of abstract data types.

1.3: The List ADT: Simple Array implementation of lists.


As stated above, all the data elements of an array are stored at contiguous locations in the main memory. The name of the
array represents the base address or the address of the first element in the main memory. Each element of the array is
represented by proper indexing.
We can define the indexing of an array in the below ways –
• 0 (zero-based indexing): The first element of the
array will be arr[0].
• 1 (one-based indexing): The first element of the
array will be arr[1].
• n (n - based indexing): The first element of the
array can reside at any random index number.
• In the above image, we have shown the memory
allocation of an array arr of size 5. The array
follows a 0-based indexing approach. The base
address of the array is 100 bytes. It is the address
of arr[0]. Here, the size of the data type used is 4
bytes; therefore, each element will take 4 bytes in
the memory.
Array / List-based representation and operations:
How to access an element from the array?
We required the information given below to access any random element from the array –
• Base Address of the array.
• Size of an element in bytes.
• Type of indexing, array follows.
The formula to calculate the address to access an array element :
Byte address of element A[i] = base address + size * ( i - first index)

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)

Space Complexity: In array, space complexity for worst case is O(n).


Advantages of Array:
• Array provides the single name for the group of variables of the same type. Therefore, it is easy to remember the
name of all the elements of an array.
• Traversing an array is a very simple process; we just need to increment the base address of the array in order to
visit each element one by one.
• Any element in the array can be directly accessed by using the index.
Disadvantages of Array:
• Array is homogenous. It means that the elements with similar data type can be stored in it.
• In array, there is static memory allocation that is size of an array cannot be altered.
• There will be wastage of memory if we store less number of elements than the declared size.
Conclusion: In this session, we have discussed the special data structure, i.e., array, and the basic operations performed on
it. Arrays provide a unique way to structure the stored data such that it can be easily accessed and can be queried to fetch
the value using the index.

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.

Important Points to be Remembered:


 The first node is called the head; it points to the first node of the list and helps us access every other element in
the list.
 Always next part of the last node must be NULL.
Representation of Single Linked List

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;

Operations on Single Linked List:


The following operations are performed on a Single Linked List:
1. Creation 2. Insertion 3. Deletion 4.Display (or) Traversing 5.Searching
Before we implement actual operations, first we need to set up an empty list. First, perform the
following steps before implementing actual operations.
Step 1 - Include all the header files which are used in the program.
Step 2 - Declare all the user defined functions.
Step 3 - Define a Node structure with two members data and next
Step 4 - Define a Node pointer 'head' and set it to NULL.
Step 5 - Implement the main method by displaying operations menu and make suitable function calls in the main
method to perform user selected operation.
1.Creation:
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, set head = ptr and define a Node pointer 'temp' and initialize with 'head'.
Step 4: If it is Not Empty then, set temp->next=ptr, temp= temp->next.
Example:
Step 1:Create a newnode named "ptr" and store the values(ptr->data=num,ptr->next=NULL)
data next
10 NULL
ptr 1000

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

Step 3:Otherwise Link previous node with new node(temp->next=ptr)


data next data next
10 2000 20 NULL
head temp 1000 ptr 2000

step 4:Make newnode ptr as temp(temp=ptr)


data next data next
10 2000 20 NULL
head 1000 temp 2000

Step 5:Repeat Step 1,2 3 and 4 to insert next nodes


data next data next data next
10 2000 20 3000 30 NULL
head 1000 2000 temp 3000

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:

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, set ptr→next = NULL and head = ptr.
Step 4 - If it is Not Empty then, set ptr→next = head and head = ptr.
Example:
Existing list with 20,30 and 40 values
data next data next data next
20 3000 30 4000 40 NULL
head 2000 3000 4000

Step 1:Create a newnode named "ptr" and store the value(ptr->data=num,ptr->next=NULL)


data next data next data next data next
10 NULL 20 3000 30 4000 40 NULL
ptr 1000 head 2000 3000 4000

Step 2:Link newnode with the head node(ptr->next=head)


data next data next data next data next
10 2000 20 3000 30 4000 40 NULL
ptr 1000 head 2000 3000 4000

Step 3:Make newnode as head node(head=ptr)


data next data next data next data next
10 2000 20 3000 30 4000 40 NULL
head 1000 2000 3000 4000

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;
}
}

Inserting At End of the list:

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 1:Create a newnode named "ptr" and store the values(ptr->data=num,ptr->next=NULL)


data next data next data next data next
10 2000 20 3000 30 NULL 40 NULL
head 1000 2000 3000 ptr 4000

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

Step 3:Link last node with the newnode called ptr(temp->next=ptr)


data next data next data next data next
10 2000 20 3000 30 4000 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)

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, set ptr->next=NULL and head = ptr.
Step 4 - If it is Not Empty then, define a node pointer temp and initialize with head.( temp=head )
Step 5 - Keep moving the temp to its next node until it reaches to the node after which we want to insert the newNode
Step 6 - Finally, Set 'ptr → next = temp→ next' and 'temp → next = ptr'
diagram:
program:
int insert_pos() {
int pos,i=1,num;
if(head==NULL)
{
printf("List is empty!!");
return 0;
}
ptr=(struct node*)malloc(sizeof(struct node));
printf("Enter data:");
scanf("%d",&num);
printf("Enter position to insert:");
scanf("%d",&pos);
ptr->data=num;
ptr->next=NULL;
temp=head;
while(i<pos)
{
temp=temp->next;
i++;
}
ptr->next=temp->next;
temp->next=ptr;
return 0;
}
3. Deletion: In a single linked list, the deletion operation can be performed in three ways. They are as follows...
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

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 → next == NULL)
Step 5 - If it is TRUE then set head = NULL and delete temp (Setting Empty list conditions) Step 6 - If it is FALSE then set
head = temp → next, and delete temp.
Step 6 - If it is FALSE then set head = temp → next, and delete temp.
Diagram:
Deleting from beginning

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);
}
}
}

Deleting from End of 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 'temp1' and initialize 'temp' with head.
Step 4. Check whether list has only one Node (temp → next == NULL)
Step 5. If it is TRUE. Then, set head = NULL and delete temp. And terminate the function.
Step 6. If it is FALSE. Then, set 'temp1 = temp ' and move temp to its next node. Repeat the same until it reaches to the
last node in the list. (until temp → next == NULL)
Step 7. Finally, Set temp1 → next = NULL and delete temp.
Diagram:
Deleting at Ending

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

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() {
printf("The Elements are \n");
temp=head;
while(temp!=NULL)
{
printf("%d", temp->data);
temp=temp->next;
}
printf("NULL");
}
5. Searching:

Step 1-Initialize a node pointer, temp=head.


Step 2-Input element to search from user. Store it in some variable say "key".
Step 3-Declare a variable to store index of found element through list, say "count=0".
Step 4-Do following while temp is not NULL temp->data == key , if the condition is true, The element is
found.
Step 5-otherwise ,increment count ( count++) and move temp to its next node (temp = temp->next )
Step 6-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;
}

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

SINGLY LINKED LIST ADVANTAGE


1) Insertions and Deletions can be
done easily.
2) It does not need movement of
elements for insertion and
deletion.
3) It space is not wasted as we can
get space according to our
requirements.
4) Its size is not fixed.
5) It can be extended or reduced
according to requirements.
6) Elements may or may not be
stored in consecutive memory
available
7) It is less expensive.
DISADVANTAGE

1) It requires more space as


pointers are also stored with
information.
2) Different amount of time is
required to access each element.
3) If we have to go to a particular
element then we have to go
through all those elements that
come before that element.
4) we can not traverse it from last
& only from the beginning.
5) It is not easy to sort the
elements stored in the linear
linked list.

Applications of Linked Lists


Graphs, queues, and stacks can be
implemented by using Linked List
SINGLY LINKED LIST ADVANTAGE :
1) Insertions and Deletions can be done easily.
2) It does not need movement of elements for insertion and deletion.
3) It space is not wasted as we can get space according to our requirements.
4) Its size is not fixed.
5) It can be extended or reduced according to requirements.
6) Elements may or may not be stored in consecutive memory available
7) It is less expensive.
DISADVANTAGE :
1) It requires more space as pointers are also stored with information.
2) Different amount of time is required to access each element.
3) If we have to go to a particular element then we have to go through all those elements that come before that element.
4) We cannot traverse it from last & only from the beginning.
5) It is not easy to sort the elements stored in the linear linked list.
Applications of Linked Lists: Graphs, queues, and stacks can be implemented by using Linked List.

1.5: Double Linked Lists(Or) TWO WAY LINKED LIST:


 Double linked list is a sequence of elements in
which every element has links to its previous
element and next element in the sequence.
 In a double linked list, every node has a link to its
previous node and next node.
 So, we can traverse forward by using the next
field and can traverse backward by using the
previous field.
 Every node in a double linked list contains three
fields and they are shown in the following figure...

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:

Important points to be Remembered


 In double linked list, the first node must be always pointed by head.
 Always the previous field of the first node must be NULL.
 Always the next field of the last node must be NULL.
Basic structure of a Double Linked List:
Each node of a singly linked list follows a common basic structure.
struct node
{
int data;
struct node *previous;
struct node *next;
}
Operations on Double Linked List
In a double linked list, we perform the following operations...
1. Create 2. Insertion 3.Deletion 4.Display 5.Searching
1. Creation: Before we implement actual operations, first we need to setup empty list. First perform the following steps
before implementing actual operations.
Step 1 - Include all the header files which are used in the program.
Step 2 - Declare all the user defined functions.
Step 3 - Define a Node structure with Three members previous, data and next
Step 4 - Define a Node pointer 'head' and set it to NULL.
Step 5 - Create a newNode with given value, Say "ptr".
Step 6- Check whether list is Empty (head == NULL).
Step 7- If it is Empty then, set head = ptr and define a Node pointer 'temp' and initialize with 'head'.
Step 8- If it is Not Empty then, set temp->next=ptr, ptr->previous=temp and temp =ptr.
Program:
#include<stdio.h>
#include<conio.h>
#include<process.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
struct node *previous;
};
struct node *head=NULL;
void create()
{
struct node *ptr,*temp;
int i,n,val;
printf("Enter Number of Elements :");
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->previous=NULL;
ptr->next=NULL;
if(head==NULL)
{
head=ptr;
temp=head;
}
else
{
temp->next=ptr;
ptr->previous=temp;
temp=ptr;
}
}
}
2. Insertion: In a double linked list, the insertion operation can be performed in three ways as follows...
1. Inserting At Beginning of the list
2. Inserting At End of the list
3. Inserting At Specific location in the list
We can use the following steps to insert a new node at
Inserting at Beginning of the list:
beginning of the double linked list...
Step 1 - Create a newNode with given value, Say “ptr“ and ptr → previous as NULL.
Step 2 - Check whether list is Empty (head == NULL)
Step 3 - If it is Empty then, assign NULL to ptr → next and ptr to head.
Step 4 - If it is not Empty then, assign head to ptr → next, ptr to head→ previous and ptr to head.
Program:
void insert_beg() {
struct node *ptr; int num;
ptr=(struct node*)malloc(sizeof(struct node));
printf("Enter data:");
scanf("%d",&num);
ptr->data=num;
ptr->previous=NULL;
if(head==NULL)
{
ptr->next = NULL;
head = ptr;
}
else
{
ptr->next = head;
head->previous=ptr;
head = ptr;
}
}
Inserting at End of the list: We can use the following steps to insert a new node at end of the
double linked list...
Step 1 - Create a newNode with given value, Say “pt“ and ptr → next as NULL.
Step 2 - Check whether list is Empty (head == NULL)
Step 3 - If it is Empty, then assign NULL to ptr → previous and ptr to head.
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 - Assign ptr to temp → next and temp to ptr → previous.
program:

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;
}

1.6: Circular Linked List:


 A circular linked list is a sequence of elements in which every element has a link to its next element in the sequence
and the last element has a link to the first element.
 That means circular linked list is similar to the single linked list except that the last node points to the first node in
the list

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");

while(ptr -> next != head)


{

printf("%d\n", ptr -> data);


ptr = ptr -> next;
}
printf("%d\n", ptr -> data);
}
}
void search()
{
struct node *ptr;
int item,i=0,flag=1;
ptr = head;
if(ptr == NULL)
{
printf("\nEmpty List\n");
}
else
{
printf("\nEnter item which you want to search?\n");
scanf("%d",&item);
if(head ->data == item)
{
printf("item found at location %d",i+1);
flag=0;
}
else
{
while (ptr->next != head)
{
if(ptr->data == item)
{
printf("item found at location %d ",i+1);
flag=0;
break;
}
else
{
flag=1;
}
i++;
ptr = ptr -> next;
}
}
if(flag != 0)
{
printf("Item not found\n");
}
}
}
Advantages: - Circular list are frequency used instead of ordinary linked list because in circular list all nodes contain a valid
address. The important feature of circular list is as follows.
(1) In a circular list every node is accessible from a given node.
(2) Certain operations like concatenation and splitting becomes more efficient in circular list.
Disadvantages: Without some conditions in processing it is possible to get into an infinite Loop.

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:

Real life examples of stacks are:

The following operations are performed on the stack


1. Push (To insert an element on to the stack)
2. Pop (To delete an element from the stack)
3. Display (To display elements of the stack)
STACK IMPLEMENTATION: Stack data structure can be implemented in two ways. They are as follows...
1. Stack using Array
2. Stack using Linked List

1. Stack Using Array


 A stack data structure can be implemented using a one-dimensional array. But stack implemented using array
stores only a fixed number of data values.
 Just define a one dimensional array of specific size and insert or delete the values into that array by using LIFO
principle with the help of a variable called 'top'. Initially, the top is set to -1.
 Whenever we want to insert a value into the stack, increment the top value by one and then insert.
 Whenever we want to delete a value from the stack, then delete the top value and decrement the top value by
one.
Stack Operations using Array: A stack can be implemented using array as follows...
Before implementing actual operations, first follow the below steps to create
an empty stack.
Step
Example
1 - Include all the header files which are used in the program and define a constant 'SIZE' with specific value.
Step 2 - Declare all the functions used in stack implementation.
 If we want to create a stack by inserting 10, 20, 30 and 40.
Step 3 - Create a one dimensional array with fixed size (int stack[SIZE])
Step 4 - Define
Thena10 becomes
integer the bottom-most
variable element
'top' and initialize withand
'-1'.40 is top
(int the top-most
= -1) element.
Step 5- In The
mainlast inserteddisplay
method, element 40 iswith
menu at Top
list of
of the stack as and
operations shown in the
make belowfunction
suitable figure. calls to perform operation
selected by the user on the stack.
3 3 3 3 top-> 3 40 top-> 3 40
1. push(value)
2
- Inserting2value into the stack 2 top-> 2 30 2 30 2 30
 1 In a stack, push()1 is a function top->
used1to insert
20 an element1 into
20the stack. 1 20 1 20
0 top-> 0 10 0 10 0 10 0 10 0 10
 In a stack, the new element is always inserted at top position.
 top=-1
Push function takespush one10integer value push
as parameter
20 and inserts
push 30 that value into
pushthe
40 stack. push 50
Empty Stack top=Max-1
We can use the following steps to push an element on to the stack...
Overflow

Figure: Push operations on Stack

// write a function to insert an element in to the stack.


void push(int value) {
if(top == SIZE-1)
printf("\nStack is Full!!! Insertion is not possible!!!");
else
{
top++;
stack[top] = value;
}
}
2. pop() - Delete a value from the Stack
 In a stack, pop() is a function used to delete an element from the stack.
 In a stack, the element is always deleted from top position.
 Pop function does not take any value as parameter.
We can use the following steps to pop an element from the stack...
Example:

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

pop 40 pop 30 pop 20 pop 10 top=-1


Underflow

Fig:Pop operations on Stack

// write a function to delete an element from the stack.


void pop() {
if(top == -1)
printf("\nStack is Empty!!! Deletion is not possible!!!");
else
{
printf("\nDeleted : %d", stack[top]);
top--;
}
}
3. display() - Displays the elements of a Stack: We can use the following steps to display the
elements of a stack...
Step 1: Check whether stack is EMPTY. (top == -1)
Step 2: If it is EMPTY, then display "Stack is EMPTY!!!" and terminate the function.
Step 3: If it is NOT EMPTY, then define a variable 'i' and initialize with top. Display stack[i] value and decrement i value
by one (i--).
Step 3: Repeat above step until i value becomes '0'.

// write a function to display an elements in the stack.


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]);
}
}
Implementation of Stack using Array:

#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 / - *

b) EVALUATION OF THE POSTFIX EXPRESSION:


#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<ctype.h>
void push(char);
char pop(void);
char ex[50],s[50],op1,op2; int i,top=-1;
void main()
{
clrscr();
printf("Enter the expression:");
gets(ex);
for(i=0;ex[i]!='\0';i++)
{
if(isdigit(ex[i]))
push(ex[i]-48);
else
{
op2=pop();
op1=pop();
switch(ex[i])
{
case '+':push(op1+op2); break;
case '-':push(op1-op2); break;
case '*':push(op1*op2); break;
case '/':push(op1/op2); break;
case '%':push(op1%op2); break;
case '^':push(pow(op1,op2)); break;
}
}
}
printf("result is :%d",s[top]); getch();
}
void push(char a)
`{
s[++top]=a;
}
char pop()
{ return(s[top--]);
}
OUTPUT:
Enter the expression: 384 * 2 / +83----
Result is: 14
What is an Expression?

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

6) Insert 50(Queue is Full) 10)Delete(queue is empty)


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

1. Queue Using Array


 A queue data structure can be implemented using one dimensional array.
 The queue implemented using array stores only fixed number of data values.
 Just define a one dimensional array of specific size and insert or delete the values into that array by using FIFO
(First In First Out) principle with the help of variables 'front' and 'rear'.
 Initially both 'front' and 'rear' are set to -1.
 Whenever, we want to insert a new value into the queue, increment 'rear' value by one and then insert at that
position.
 Whenever we want to delete a value from the queue, then delete the element which is at 'front' position and
increment 'front' value by one.
Queue Operations using Array: Queue data structure using array can be implemented as
follows...
Before we implement actual operations, first follow the below steps to create
an empty queue.
Step 1 - Include all the header files which are used in the program and define a constant 'SIZE' with specific value.
Step 2 - Declare all the user defined functions which are used in queue implementation.
Step 3 - Create a one dimensional array with above defined SIZE (int queue[SIZE])
Step 4 - Define two integer variables 'front' and 'rear' and initialize both with '-1'. (int front = -1, rear = -1)
Step 5 - Then implement main method by displaying menu of operations list and make suitable function calls to
perform operation selected by the user on queue.
1. enQueue(value) - Inserting value into the queue
 In a queue data structure, enQueue() is a function used to insert a new element into the queue.
 In a queue, the new element is always inserted at rear position.
 The enQueue() function takes one integer value as a parameter and inserts that value into the queue.
We can use the following steps to insert an element into the queue...
Step 1 - Check whether queue is FULL. (rear == SIZE-1)
Step enQueue(int
void 2 - If it is FULL, then display "Queue is FULL!!! Insertion is not possible!!!" and terminate the function.
value)
{Step 3 - If it is NOT FULL, then increment rear value by one (rear++) and set queue[rear] = value.
program:
if(rear == SIZE-1)
printf("\nQueue is Full!!! Insertion is not possible!!!");
else
Step{ 1 - Check whether queue is EMPTY. (front == rear)
Step
void if(front
2 - If it==
deQueue() is -1)
EMPTY, then display "Queue is EMPTY!!! Deletion is not possible!!!" and terminate the function.
Step
{ front
3 - =
If 0;
it is NOT EMPTY, then increment the front value by one (front ++). Then display queue[front] as deleted
rear++;
element.
if(front == Then rear)check whether both front and rear are equal (front == rear), if it TRUE, then set both front and rear to '-
queue[rear]= rear == -1).
1' printf("\nQueue
(front value;
is Empty!!! Deletion is not possible!!!");
printf("\nInsertion
program:
else success!!!");
}{
} printf("\nDeleted : %d", queue[front]);
2. deQueue() - Deleting a value from the Queue
voidfront++;
display()
{ 
if(front In ==a queue
rear) data structure, deQueue() is a function used to delete an element from the queue.
 In
front
if(rear === a -1)
rearqueue,
= -1; the element is always deleted from front position.
 The deQueue()
} printf("\nQueue is Empty!!!"); function does not take any value as parameter.
We
} elsecan use the following steps to delete an element from the queue...
3. display()
{ - Displays the elements of a Queue: We can use the following steps to display the elements of a queue...
Step int1 i;- Check whether queue is EMPTY. (front == rear)
Step 2 - If it is EMPTY,
printf("\nQueue then display
elements "Queue is EMPTY!!!" and terminate the function.
are:\n");
Step 3 - If it is NOT
for(i=front; EMPTY,
i<=rear; i++) then define an integer variable 'i' and set 'i = front+1'.
Step printf("%d\t",queue[i]); value and increment 'i' value by one (i++). Repeat the same until 'i' value reaches
4 - Display 'queue[i]'
to }rear (i <= rear)
program:
}
Implementation of Queue Datastructure using Array
#include<stdio.h>
#include<conio.h>
#define SIZE 10
void enQueue(int);
void deQueue();
void display();
int queue[SIZE], front = -1, rear = -1;
void main()
{
int value, choice;
clrscr();
while(1)
{
printf("\n\n***** MENU *****\n");
printf("1. Insertion\n2. Deletion\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);
enQueue(value);
break;
case 2: deQueue();
break;
case 3: display();
break;
case 4: exit(0);
default: printf("\nWrong selection!!! Try again!!!");
}
}
}
void enQueue(int value)
{
if(rear == SIZE-1)
printf("\nQueue is Full!!! Insertion is not possible!!!");
else
{
if(front == -1)
front = 0;
rear++;
queue[rear] = value;
printf("\nInsertion success!!!");
}
}
void deQueue()
{
if(front == rear)
printf("\nQueue is Empty!!! Deletion is not possible!!!");
else {
printf("\nDeleted : %d", queue[front]);
front++;
if(front == rear)
front = rear = -1;
}
}
void display() {
if(rear == -1)
printf("\nQueue is Empty!!!");
else {
int i;
printf("\nQueue elements are:\n");
for(i=front; i<=rear; i++)
printf("%d\t",queue[i]);
}
}

Stacks and Queue implementation using linked list.


Stack Using Linked List:
#include<stdio.h>
#include<conio.h>
struct node
{
int data;
struct node *next;
}*top = NULL;

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);
}
}

Queue Using Linked List:


 The queue which is implemented using a linked list can work for an unlimited number of values.
 That means, queue using linked list can work for the variable size of data (No need to fix the size at the beginning
of the implementation).
 The Queue implemented using linked list can organize as many data values as we want.
In linked list implementation of a queue, the last inserted node is always pointed by 'rear' and the first node is
always pointed by 'front'.
Example:

 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 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;
}
}
2. deQueue() - Deleting an Element from Queue: We can use the following steps to delete a node
from the queue...
Step 1 - Check whether queue is Empty (front == NULL).
Step 2 - If it is Empty, then display "Queue is Empty!!! Deletion is not possible!!!" and terminate from the function
Step 3 - If it is Not Empty then, define a Node pointer 'temp' and set it to 'front'.
Step 4 - Then set 'front = front → next' and delete 'temp' (free(temp)).
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 :

Let the element to be searched is K = 41


Now, start from the first element and compare K with each element of the array. The value of K, i.e., 41, is not matched
with the first element of the array. So, move to the next element. And follow the same process until the respective element
is found.

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).

Binary Search Algorithm:


The basic steps to performing Binary Search are:
• Begin with the mid element of the whole array as a search key.
• If the value of the search key is equal to the item then return an index of the search key.
• Or if the value of the search key is less than the item in the middle of the interval, narrow the interval to the
lower half.
• Otherwise, narrow it to the upper half.
• Repeatedly check from the second point until the value is found or the interval is empty.
Binary Search Algorithm can be implemented in the following two ways
1. Iterative Method 2. Recursive Method
// Iterative Binary Search in C
int binarySearch(int array[], int x, int low, int high)
{
// Repeat until the pointers low and high meet each other
while (low <= high)
{
int mid = low + (high - low) / 2;
if (array[mid] == x)
return mid;
if (array[mid] < x)
low = mid + 1;
else
high = mid - 1;
}
return -1;
}
int main(void)
{
int array[] = {3, 4, 5, 6, 7, 8, 9};
int x = 4;
int n = sizeof(array) / sizeof(array[0]);
int result = binarySearch(array, x, 0, n - 1);
if (result == -1)
printf("Not found");
else
printf("Element is found at index %d", result);
return 0;
}

// Recursive Binary Search


int binarySearch(int arr[], int l, int r, int x)
{
if (r >= l)
{
int mid = l + (r - l) / 2;
// If the element is present at the middle itself
if (arr[mid] == x)
return mid;
// If element is smaller than mid, then it must present in left subarray
if (arr[mid] > x)
return binarySearch(arr, l, mid - 1, x);
// Else the element can only be present in right subarray
return binarySearch(arr, mid + 1, r, x);
}
return -1; // We reach here when element is not present in array
}
int main(void)
{
int arr[] = { 2, 3, 4, 10, 40 };
int x = 10;
int n = sizeof(arr) / sizeof(arr[0]);
int result = binarySearch(arr, 0, n - 1, x);
if (result == -1) ? printf("Element is not present in array") : printf("Element is present at index %d", result);
return 0;
}

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.

2. Now, the first two elements are sorted.


Take the third element and compare it with the elements
on the left of it. Placed it just behind the element smaller
than it. If there is no element smaller than it, then place it
at the beginning of the array.

3. Similarly, place every unsorted element in its correct position


step4:

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

To handle the collision,


 This technique creates a linked list to the slot for which collision occurs.
 The new key is then inserted in the linked list.
 These linked lists to the slots appear like chains.
 That is why, this technique is called 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:

 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.
 So, key 73 will be inserted in bucket-3 of
the hash table as

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

 Degree of a node is Example Here,


the total number of children  Degree of node A = 2
of that node.  Degree of node B = 3
 Degree of a tree is the  Degree of node C = 2
highest degree of a node  Degree of node D = 0
among all the nodes in the  Degree of node E = 2
tree.  Degree of node F = 0
 Degree of node G = 1
 Degree of node H = 0
 Degree of node I = 0
 Degree of node J = 0
 Degree of node K = 0
7. Internal Node
 The node which has at Example Here, nodes A, B, C, E and G
least one child is called as are internal nodes.
an internal node.
 Internal nodes are also
called as non-terminal nodes.
 Every non-leaf node is
an internal node.

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.

Types of Binary Tree


1. Rooted Binary Tree 2. Full / Strictly Binary Tree 3.Complete / Perfect Binary Tree 4. Almost Complete Binary Tree 5.
Skewed Binary Tree
1. Rooted Binary Tree
A rooted binary tree is a binary tree that satisfies the following 2 Example
properties-
 It has a root node.
 Each node has at most 2 children.

2. Full / Strictly Binary Tree


 A binary tree in Example Here,
which every node  First binary tree is
has either 0 or 2 not a full binary
children is called as tree.
a Full binary tree.  This is because node
 Full binary tree is C has only 1 child.
also called
as Strictly binary
tree.

3. Complete / Perfect Binary Tree


A complete binary tree is a Example Here,
binary tree that satisfies the  First binary tree is not a
following 2 properties- complete binary tree.
 Every internal node has  This is because all the
exactly 2 children. leaf nodes are not at
 All the leaf nodes are at the same level.
the same level.

Complete binary tree is also


called as Perfect binary tree.

4. Almost Complete Binary Tree


An almost complete binary tree is Example Here,
a binary tree that satisfies the  First binary tree is not an
following 2 properties- almost complete binary
 All the levels are tree.
completely filled except  This is because the last
possibly the last level. level is not filled from left
 The last level must be to right.
strictly filled from left to
right.

5. Skewed Binary Tree


A skewed binary tree is a binary tree that satisfies the Example
following 2 properties-
 All the nodes except one node has one and only
one child.
 The remaining node has no child.
OR
A skewed binary tree is a binary tree of n nodes such that
its depth is (n-1).

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 Trees-find, findMin and findMax, insert, delete operations.


Binary Search Tree:
 Binary tree is a special tree data structure.
 In a binary tree, each node can have at most 2 children.
 In a binary tree, nodes may be arranged in any random order.

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.

Search Operation in BST

The search operation is performed as follows...


Step 1 - Read the search element from the user.
Step 2 - Compare the search element with the value of root node in the tree.
Step 3 - If both are matched, then display "Given node is found!!!" and terminate the function
Step 4 - If both are not matched, then check whether search element is smaller or larger than that node value.
Step 5 - If search element is smaller, then continue the search process in left subtree.
Step 6- If search element is larger, then continue the search process in right subtree.
Step 7 - Repeat the same until we find the exact element or until the search element is compared with the leaf node
Step 8 - If we reach to the node having the value equal to the search value then display "Element is found" and
terminate the function.
Step 9 - If we reach to the leaf node and if it is also not matched with the search element, then display "Element is not
found" and terminate the function.
Example:
Consider key = 45 has to be  We start our search from the root
searched in the given BST- node 25.
 As 45 > 25, so we search in 25’s
right subtree.
 As 45 < 50, so we search in 50’s left
subtree.
 As 45 > 35, so we search in 35’s
right subtree.
 As 45 > 44, so we search in 44’s
right subtree but 44 has no
subtrees.
 So, we conclude that 45 is not
present in the above BST.

Deletion Operation in BST


Deleting a node from Binary search tree includes following three cases...
Case 1: Deleting a Leaf node (A node with no children)
Case 2: Deleting a node with one child
Case 3: Deleting a node with two children

Case 1: Deleting a leaf node


We use the following steps to delete a leaf node from BST...
Step 1 - Find the node to be deleted using search operation
Step 2 - Delete the node using free function (If it is a leaf) and terminate the function.
Example:

Consider the following example where node with value = 20 is deleted from the BST-

Case 2: Deleting a node with one child


We use the following steps to delete a node with one child from BST...
Step 1 - Find the node to be deleted using search operation
Step 2 - If it has only one child then create a link between its parent node and child node.
Step 3 - Delete the node using free function and terminate the function.
Example:
Consider the following example where node with value = 30 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:

 Visit to the right subtree of the deleting node.


 Pluck the least value element called as inorder successor.
 Replace the deleting element with its inorder successor.
Example
Consider the following example where node with value = 15 is deleted from the BST-

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

Depth First Traversal


Following three traversal techniques fall under Depth First Traversal-
1. Preorder Traversal
2. Inorder Traversal
3. Postorder Traversal

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)

Left → Root → Right


Example
Consider the following example

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.

Implementation of Tree Traversal Methods


#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node* left;
struct node* right;
};
void inorder(struct node* root)
{
if(root == NULL) return;
inorder(root->left);
printf("%d ->", root->data);
inorder(root->right);
}
void preorder(struct node* root)
{
if(root == NULL) return;
printf("%d ->", root->data);
preorder(root->left);
preorder(root->right);
}
void postorder(struct node* root)
{
if(root == NULL) return;
postorder(root->left);
postorder(root->right);
printf("%d ->", root->data);
}
struct node* createNode(value)
{
struct node* newNode = malloc(sizeof(struct node));
newNode->data = value;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
struct node* insertLeft(struct node *root, int value)
{
root->left = createNode(value);
return root->left;
}
struct node* insertRight(struct node *root, int value)
{
root->right = createNode(value);
return root->right;
}
int main()
{
struct node* root = createNode(1);
insertLeft(root, 12);
insertRight(root, 9);
insertLeft(root->left, 5);
insertRight(root->left, 6);
printf("Inorder traversal \n");
inorder(root);
printf("\nPreorder traversal \n");
preorder(root);
printf("\nPostorder traversal \n");
postorder(root);
}

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

Example of AVL Tree

The above tree is a binary search tree and every node is satisfying balance factor condition. So this tree is said to be an AVL
tree.
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...

Right Left Rotation (RL Rotation)1


The RL Rotation is sequence of single right rotation followed by single left rotation. In RL Rotation, at first every node moves
one position to right and one position to left from the current position. To understand RL Rotation, let us consider the
following insertion operation in AVL Tree.
Operations on an AVL Tree
The following operations are performed on AVL tree...
1. Insertion
2. Search
3. Deletion
Insertion Operation in AVL Tree
In AVL Tree, a new node is always inserted as a leaf node. The insertion operation is performed as follows...
Step 1 - Insert the new element into the tree using Binary Search Tree insertion logic.
Step 2 - After insertion, check the Balance Factor of every node.
Step 3 - If the Balance Factor of every node is 0 or 1 or -1 then go for next operation.
Step 4 - If the Balance Factor of any node is other than 0 or 1 or -1 then that tree is said to be imbalanced. In this case,
perform suitable Rotation to make it balanced and go for next operation.
Example: Construct AVL Tree for the following sequence of numbers- 50 , 20 , 60 , 10 , 8 , 15 , 32 , 46 , 11 , 48
Solution:
Insert 50
intiate: 0
50

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

To balance the tree,


 Find the first imbalanced node on the path from the newly inserted node (node 8) to the root node.
 The first imbalanced node is node 20.
 Now, count three nodes from node 20 in the direction of leaf node.
 Then, use AVL tree rotation to balance the tree.
Following this, we have-
2 1

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

 As 15 > 10, so insert 15 in 10’s right sub tree. 50


 As 15 < 20, so insert 15 in 20’s left sub tree. -1 0
10 60
0 1
8 20

0 15

Tree is Imbalanced

To balance the tree


 Find the first imbalanced node on the 2 0
path from the newly inserted node
50 20
(node 15) to the root node.
 The first imbalanced node is node 50. -1 0 0 1 -1
10 60 10 50
 Now, count three nodes from node 50 in
the direction of leaf node. 0 1 LR Rotation 0 0 0
 Then, use AVL tree rotation to balance 8 20 8 15 60
the tree.
5
0 15
Tree is Imbalanced Tree is Balanced

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

 As 11 > 10, so insert 11 in 10’s right sub tree. 10 20 50

 As 11 < 15, so insert 11 in 15’s left sub tree. -1


10
1 1
50
8 15 32 60
0 1 -1 0
8 15 32 60
0 46 0
11 46

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

To balance the tree,


-1 0
 Find the first imbalanced node on the path
from the newly inserted node (node 48) to 20 20

the root node. 2 1


-1 50-1 -1 50-1
 The first imbalanced node is node 32. 10 10

 Now, count three nodes from node 32 in 1 1


0 15 32 -2 0 LL Rotation 0 15 46 0 0
the direction of leaf node. 8 60 8 60

 Then, use AVL tree rotation to balance the 0


0 -1 -1 0 -1 0
tree. 11 46 11 32 48

0 Tree is balanced
Tree is Imbalanced 48

Following this, we have-


Deletion Operation in an AVL Tree
Deletion in an AVL Tree
 Deletion in an AVL tree is similar to that in a BST.
 Deletion of a node tends to disturb the balance factor. Thus to balance the tree, we again use the Rotation
mechanism.
Deletion in AVL tree consists of two steps:
o Removal of the node: The given node is removed from the tree structure. The node to be removed can either be
a leaf or an internal node.
o Re-balancing of the tree: The elimination of a node from the tree can cause disturbance to the balance factor of
certain nodes. Thus it is important to re- balance the nodes; since the balance factor is the primary aspect
that ensures the tree is an AVL Tree.
Deleting a node from Binary search tree includes following three cases...
Case 1: Deleting a Leaf node (A node with no children)
Case 2: Deleting a node with one child
Case 3: Deleting a node with two children
Note: There are certain points that must be kept in mind during a deletion process.
 If the node to be deleted is a leaf node, it is simply removed from the tree.
 If the node to be deleted has one child node, the child node is replaced with the node to be deleted simply.
 If the node to be deleted has two child nodes then,
o Either replace the node with it’s inorder predecessor , i.e, the largest element of the left sub tree.
o Or replace the node with it’s inorder successor , i.e, the smallest element of the right sub tree.
Example:
0
15
0 0
12 54
0 -1 1 0
8 13 18 60
0 0 0 0 0 0
5 9 14 16 56 70

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 various operations that can be done on a B-Tree are:


 Insertion
 Searching
 Deletion

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 initiates the structure Bnode:


#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#define max 5/* A B-tree of oreder 6*/
#define MIN 2
struct Bnode
{
int children;
int data[MAX+1];
struct Bnode* child[MAX+1];
}*root=NULL;
/*function declaration*/
void insert(int);
struct Bnode* search(int, struct Bnode*,int *);
int setval(int, struct Bnode*, int*, struct Bnode*,int*);
void split(int, Struct Bnode*, struct Bnode*,int, int*,struct Bnode**);
void del(int);
int delhelp(int, struct Bnode);
void clear(struct Bnode*, int);
void copysucc(struct Bnode*,int);
void restore(struct Bnode*int);
void Rshift(int);
void Lshift(int);
void merge(int);
void show();
void display(struct Bnode*);
void deltree(struct Bnode*);
The above code also declares the functions, insert(), setval(), split(), del(), delhelp(), clear(), copysucc(), restore(), Rshift(),
Lshift(), merge(), show(), display() and deltree().
The following code defines the function, insert(), which enables you to insert a node in the tree:
/*definition of Functions*/
void insert(int data)
{
int i;
struct Bnode *c,*n;
if(satval(data, root, &i,&c)!=0)
{
n=(struct Bnode*)malloc(sizeof(struct Bnode));
n->children=1;
n->data[1]=i;
n->child[0]=root;
n->child[1]=c;
root=n;
}
}

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);
}
}

Draw a B-tree of order 3 for the following sequence of keys:


2, 4, 9, 8, 7, 6, 3, 1, 5, 10

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.

Properties of Red Black Tree


1. Red - Black Tree must be a Binary Search Tree.
2. The ROOT node must be colored BLACK.
3. The children of Red colored node must be colored BLACK. (There should not be two consecutive RED nodes).
4. In all the paths of the tree, there should be same number of BLACK colored nodes.
5. Every new node must be inserted with RED color.
6. Every leaf (e.i. NULL node) must be colored BLACK.

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.

Insertion into RED BLACK Tree


 In a Red-Black Tree, every new node must be inserted with the color RED.
 The insertion operation in Red Black Tree is similar to insertion operation in Binary Search Tree. But it is inserted
with a color property.
 After every insertion operation, we need to check all the properties of Red-Black Tree.
 If all the properties are satisfied then we go to next operation otherwise we perform the following operation to
make it Red Black Tree.
1. Recolor(Change Grand parent as Red, Siblings as Black)
2. Rotation(Same side)
3. Rotation followed by Recolor(opposite side)
The insertion operation in Red Black tree is performed using the following steps...
Step 1 - Check whether tree is Empty.
Step 2 - If tree is empty then insert the newNode as Root node with color RED
Step 3 -If Root node is Red, color(Root) is changed to black and exit from the operation.
Step 4 - If tree is not Empty then insert the newNode as leaf node with color Red.
Step 5 - If the parent of newNode is Black then exit from the operation.
Step 6 - If the parent of newNode is Red then check the color of parentnode's sibling of newNode.
Step 7 - If it is colored Black or NULL then
Case 1: (Same Side)
Recolor
Opposite side rotation
Case 2: (Opposite Side)
One Side Rotate
Perform Case 1
Step 8 - If it is colored Red then perform Recolor. Repeat the same until tree becomes 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

 Here there are two consecutive Red nodes(18 & 15).


 The newNode’s parent sibling color is Red
 So we use RECOLOR to make it RED BLACK Tree.

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

 Here there are two consecutive Red nodes(15 & 17).


 The newNode’s parent sibling color is NULL. So we need rotation.
 Here, we need LR Rotaton and RECOLOR.

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

 Here there are two consecutive Red nodes(18 & 25).


 The newNode’s parent sibling color is Red and parent’s parent is not root node.
 So we use RECOLOR and Recheck.

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

 Here there are two consecutive Red nodes(25 & 40).


 The newNode’s parent sibling is NULL.
 Here, we use LL Rotaton and Recolor then Recheck.

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

 Here there are two consecutive Red nodes(40 & 80).


 The newNode’s parent sibling color is Red
 So we use RECOLOR and Recheck.

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

2. Zig-Zag Rotation 2 Insert 1


g 2 g 2
2 x
2
1
p 0 x p 1
0 1 g
0 2
x p 1 0
1 0

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

Advantages and Disadvantages of Splay Trees


The advantages of using a splay tree are:
 A splay tree gives good performance for search, insertion, and deletion operations. This advantage centres on the
fact that the splay tree is a self-balancing and a self-optimizing data structure in which the frequently accessed
nodes are moved closer to the root so that they can be accessed quickly. This advantage is particularly useful for
implementing caches and garbage collection algorithms.
 Splay trees are considerably simpler to implement than the other self-balancing binary search trees, such as red-
black trees or AVL trees, while their average case performance is just as efficient.
 Splay trees minimize memory requirements as they do not store any book-keeping data.
 Unlike other types of self-balancing trees, splay trees provide good performance (amortized O(log n)) with nodes
containing identical keys.
However, the demerits of splay trees include:
 While sequentially accessing all the nodes of a tree in a sorted order, the resultant tree becomes completely
unbalanced. This takes n accesses of the tree in which each access takes O(log n) time. For example, re-accessing
the first node triggers an operation that in turn takes O(n) operations to rebalance the tree before returning the
first node. Although this creates a significant delay for the final operation, the amortized performance over the
entire sequence is still O(log n).
 For uniform access, the performance of a splay tree will be considerably worse than a somewhat balanced simple
binary search tree. For uniform access, unlike splay trees, these other data structures provide worst-case time
guarantees and can be more efficient to use.

Comparison of Search Trees:


Search Tree Average Case Search Tree Worst Case

Insert Delete Search Insert Delete Search

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)

B Tree O(log n) O(log n) O(log n) B Tree O(log n) O(log n) O(log 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

Previous question papers with answers

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.

You might also like