20CA102
Data Structures and Algorithms
Dr.K.Kanagaraj
AP(Sr.G)/MCA
Definition
Data: Collection of raw facts
Data structure is the representation
of the logical relationship existing
between individual elements of data.
Definition
Data structure is a specialized format
for organizing and storing data in
memory that considers not only the
elements stored but also their
relationship to each other.
Introduction
• Data structure affects the design of
both structural & functional aspects of
a program.
• Program =Algorithm + Data Structure
Introduction
Data structure are normally
divided into two broad categories:
Primitive Data Structure
Non-Primitive Data Structure
Classification of Data Structure
Primitive Data Structures
• There are basic structures and directly
operated upon by the machine instructions.
Integer
Floating point number
Character
Constants
String constants
Pointers
Non Primitive Data Structure
• The Data structures that are derived from the
primitive data structures are called Non
primitive data structure.
Linear Data structures
Non-Linear Data structures
Linear Data structures
• Linear Data structures are kind of data structure that has
homogeneous elements.
• The data structure in which elements are in a sequence and
form a linear series.
• Linear data structures are very easy to implement, since the
memory of the computer is also organized in a linear
fashion.
• Some commonly used linear data structures are Stack,
Queue and Linked Lists.
Non Linear Data structures
• A Non Linear Data structures is a data
structure in which data item is connected to
several other data items.
• Non Linear data structure may exhibit either a
hierarchical relationship or parent child
relationship.
• The data elements are not arranged in a
sequential structure.
• The different non linear data structures are
trees and graphs.
Operations on Data
Structures
Traversal
Insertion
Selection
Searching
Sorting
Merging
Destroy or Delete
Arrays
• An array is defined as a set of finite
number of homogeneous elements or
same data items.
• It means an array can contain one type
of data only, either all integer, all float-
point number or all character.
One dimensional Array
• An array with only one row or column is
called one dimensional array.
• It is finite collection of n number of
elements of same type such that:
• It can be referred by indexing
• The syntax elements are stored in
continuous locations.
One dimensional Array
• Elements x to define one dimensional
array is:
• Syntax: Datatype Array_Name [Size];
• Where,
• Datatype : Type of value it can store
(Example: int, char, float)
• Array_Name: To identify the array.
• Size : The maximum number of
elements that the array can hold.
Arrays Example
Declaration of array is as follows:
int arr[10]
Where int specifies the data type or type
of elements arrays stores.
“arr” is the name of array & the number
specified inside the square brackets is
the number of elements an array can
store, this is also called size or length of
array.
Linear Array Representaion
in memory
Size of the Array
The size of array or its length is given
by the following equation:
(upperbound - lowerbound)+1
For the above array it would be (9 -
0)+1=10
where 0 is the lower bound of array and
9 is the upper bound of array.
Size of the Array
Array can always be read or written
through loop.
for(i=0;i<=9;i++)
{
scanf(“%d”,&arr[i]);
printf(“%d”,arr[i]);
}
Arrays types
• Single Dimension Array
– Array with one subscript
• Two Dimension Array
– Array with two subscripts (Rows and
Column)
• Multi Dimension Array
– Array with Multiple subscripts
Basic operations of Arrays
Traversing
Searching
Insertion
Deletion
Sorting
Merging
Traversing Arrays
• Traversing: It is used to access each
data item exactly once so that it can be
processed.
Insertion into Array
• Insertion: It is used to add a new data
item in the given collection of data
items.
Deletion from Array
• Deletion: It is used to delete an existing
data item from the given collection of
data items.
Searching in Arrays
• Searching: It is used to find out the
location of the data item if it exists in
the given collection of data items.
Linear Search
Binary Search
Linear Search
Binary Search
The binary search algorithm can be used with
only sorted list of elements.
Binary Search first divides a large array into
two smaller sub-arrays and then recursively
operate the sub-arrays.
Binary Search basically reduces the search
space to half at each step
Binary Search
Binary Search
Advantages of Arrays
• It is used to represent multiple data items of same
• type by using single name.
• It can be used to implement other data structures like
linked lists, stacks, queues, tree, graphs etc.
• Two dimensional arrays are used to represent matrices.
• Many databases include one dimensional arrays whose
elements are records.
Disadvantages of Array
• We must know in advance the how many elements are to be
stored in array.
• Array is static structure. It means that array is of fixed size. The
memory which is allocated to array cannot be increased or
decreased.
• Array is fixed size; if we allocate more memory than
requirement then the memory space will be wasted.
• The elements of array are stored in consecutive memory
locations. So insertion and deletion are very difficult and time
consuming.
Stack
• Stack is a linear data structure which
follows a particular order in which the
operations are performed.
• Insertion of element into stack is called
PUSH and deletion of element from stack
is called POP.
• The order may be LIFO(Last In First Out)
or FILO(First In Last Out).
Implementation of Stack
Using arrays (Static implementation)
Using pointer (Dynamic
implementation)
Operations on Stack
Stack( ): It creates a new stack that is empty. It needs no
parameter and returns an empty stack.
push(item): It adds a new item to the top of the stack.
pop( ): It removes the top item from the stack.
peek( ): It returns the top item from the stack but does
not remove it.
isEmpty( ): It tests whether the stack is empty.
size( ): It returns the number of items on the stack.
PUSH Operation:
The process of adding one element or
item to the stack is represented by an
operation called as the PUSH operation.
The new element is added at the
topmost position of the stack.
PUSH Operation:
ALGORITHM:
PUSH (STACK, TOP, SIZE, ITEM)
//STACK is the array with N elements. TOP is the pointer
to the top of the element of the array. ITEM to be
inserted.
Step 1: if TOP = N then [Check Overflow]
PRINT “ STACK is Full or Overflow”
Exit
[End if]
Step 2: TOP = TOP + 1 [Increment the TOP]
Step 3: STACK[TOP] = ITEM [Insert the ITEM]
Step 4: Return
POP Operation
ALGORITHM:
POP (STACK, TOP, ITEM)
STACK is the array with N elements. TOP is the pointer
to the top of the element of the array. ITEM to be
inserted.
Step 1: if TOP = 0 then [Check Underflow]
PRINT “ STACK is Empty or Underflow”
Exit
[End if]
Step 2: ITEM = STACK[TOP] [Copy the TOP Element]
Step 3: TOP = TOP-1 [Decrement the Top]
Step 4: Return
PEEK Operation
ALGORITHM:
PEEK (STACK, TOP)
//STACK is the array with N elements. TOP is the
pointer to the top of the element of the array.
Step 1: if TOP = NULL then [Check Underflow]
PRINT “ STACK is Empty or Underflow”
Exit
[End if]
Step 2: Return (STACK[TOP])
// [Return the top element of the stack]
Step 3:Exit
Application of Stacks
It is used to reverse a word. You push a given word
to stack letter by letter and then pop letter from
the stack.
“Undo” mechanism in text
Backtracking
Language Processing: Compiler’ syntax check
Conversion of decimal number to binary.
To solve tower of Hanoi
Conversion of infix expression into prefix and
postfix.
Quick sort
Runtime memory management.
Arithmetic Expression
An expression is a combination of
operands and operators that after
evaluation results in a single value.
Operand consists of constants and
variables.
Operators consists of {, +, -, *, /, ), ]etc
Types of Arithmetic Expression
Infix Expression
If an operator is in between two operands, it is
called infix expression.
Example: a + b, where a and b are operands and + is
an operator.
Postfix Expression
If an operator follows the two operands, it is called
postfix expression.
Example: ab +
Prefix Expression
If an operator precedes the two operands, it is
called prefix expression.
Example: +ab
Types of Arithmetic Expression
Postfix
Infix Expression Prefix Expression Expression
A+B*C+D ++A*BCD ABC*+D+
(A + B) * (C + D) *+AB+CD AB+CD+*
A*B+C*D +*AB*CD AB*CD*+
A+B+C+D +++ABCD AB+C+D+
Converting Infix to Prefix and Postfix
Queue
A queue is an ordered collection of items
where an item is inserted at one end
called the “rear” and an existing item is
removed at the other end, called the
“front”.
Queue
Queue is also called as FIFO list i.e. First In
First Out.
In the queue only two operations are
allowed enqueue and dequeue.
Enqueue means to insert an item into
back of the queue.
Dequeue means removing the front item.
The people standing in a railway
reservation row are an example of queue.
Memory Representation of a queue
using array
Queue is represented in memory using linear
array.
QUEUE is an array, two pointer variables called
FRONT and REAR are maintained.
The pointer variable FRONT contains the location
of the element to be removed or deleted.
The pointer variable REAR contains location of the
last element inserted.
The condition FRONT = NULL indicates that queue
is empty.
The condition REAR = N-1 indicates that queue is
full.
Memory Representation of a queue
using array
Implementation of queue
using array
Types of Queues
Simple Queue
Circular Queue
Priority Queue
Dequeue ( Double Ended Queue)
Simple Queue
Simple Queue: In simple queue insertion
occurs at the rear end of the list and
deletion occurs at the front end of the list.
Circular Queue
A circular queue is a queue in which all
nodes are treated as circular such that
the last node follows the first node.
Priority Queue
A priority queue is a queue that contains
items that have some present priority An
element can be inserted or removed from
any position depending upon some priority.
Dequeue Queue
It is a queue in which insertion and
deletion takes place at the both ends..
Operation on Queues
Queue( ): It creates a new queue that is empty.
enqueue(item): It adds a new item to the rear
of the queue.
dequeue( ): It removes the front item from the
queue.
isEmpty( ): It tests to see whether the queue is
empty.
size( ): It returns the number of items in the
queue.
Operation on Queues
Queue( ): It creates a new queue that is empty.
enqueue(item): It adds a new item to the rear
of the queue.
dequeue( ): It removes the front item from the
queue.
isEmpty( ): It tests to see whether the queue is
empty.
size( ): It returns the number of items in the
queue.
Queue Insertion (enqueue)
Queue Insertion (enqueue)
Queue Deletion (dequeue)
Queue Deletion (dequeue)
Circular Queue
Q: 0 size - 1
b c d e f
front rear
// Basic idea only!
enqueue(x) {
Q[rear] = x;
rear = (rear + 1) % size
}
// Basic idea only!
dequeue() {
x = Q[front];
front = (front + 1) % size;
return x;
}
Applications of Queue
Simulation
Various features of Operating system
Multi programming platform systems.
Different types of scheduling algorithms
Round robin technique algorithms
Printer server routines
Various application software’s is also based on
queue data structure.
Lists
A lists (Linear linked list) can be defined as a
collection of variable number of data items
called nodes
Lists are the most commonly used non
primitive data structures.
Each nodes is divided into two parts:
The first part contains the information of the
element.
The second part contains the memory address of
the next node in the list. Also called Link part.
Lists
Types of linked lists
Single linked list
Doubly linked list
Single circular linked list
Doubly circular linked list
Single linked list
A singly linked list contains two fields in each
node
an information field and the linked field.
The information field contains the data of that
node.
The link field contains the memory address of
the next node.
There is only one link field in each node, the
linked list is called singly linked list.
Single linked list
Single circular linked list
The link field of the last node contains the
memory address of the first node.
Such a linked list is called circular linked list.
In a circular linked list every node is accessible
from a given node.
Single circular linked list
Doubly linked list
It is a linked list in which each node is points
both to the next node and also to the previous
node.
In doubly linked list each node contains three
parts:
FORW : It is a pointer field that contains the
address of the next node
BACK: It is a pointer field that contains the
address of the previous node.
INFO: It contains the actual data.
Doubly linked list
In the first node, if BACK contains NULL, it
indicated that it is the first node in the list.
The node in which FORW contains, NULL
indicates that the node is the last node.
Doubly circular linked list
Operations on Linked List
Creating a linked list
Traversing a linked list
Inserting an item into a linked list.
Deleting an item from the linked list.
Searching an item in the linked list
Merging two or more linked lists.
Creating a linked list
The nodes of a linked list can be created by
the following structure declaration.
struct Node
{
int info;
struct Node *link;
}*node1, node2;
Creating a linked list
info is the information field and link is the link
field.
The link field contains a pointer variable that
refers the same node structure.
Such a reference is called as self addressing
pointer
Define the Node Structure
struct Node
{
int data;
struct Node* next;
};
Create Empty Nodes
int main()
{
struct Node* head = NULL;
struct Node* second = NULL;
struct Node* third = NULL;
// allocate 3 nodes in the heap
head = (struct Node*)malloc(sizeof(struct Node));
second = (struct Node*)malloc(sizeof(struct
Node));
third = (struct Node*)malloc(sizeof(struct Node));
Assign Values and Link the Nodes
head->data = 1; // assign data in first node
head->next = second; // Link first node with
second
second->data = 2; // assign data to second node
second->next = third;
third->data = 3; // assign data to third node
third->next = NULL;
Printing the elements in the
List
void printList (struct Node* n)
{
while (n != NULL) {
printf(" %d ", n->data);
n = n->next;
}
}
printList(head)
Insert a new node to the front
new_node->data = new_data;
/* Make next of new node as head */
new_node->next = (*head_ref);
/* move the head to point to the new
node */
(*head_ref) = new_node;
Insert a new node after the given
prev_node
/* put in the data */
new_node->data = new_data;
/* Make next of new node as next of prev_node */
new_node->next = prev_node->next;
/* move the next of prev_node as new_node */
prev_node->next = new_node;
Abstract Data Types
An abstract data type (ADT) is a set of
operations.
They are mathematical abstractions
Nowhere in an ADT's definition is there
any mention of how the set of
operations is implemented.
This can be viewed as an extension of
modular design
Abstract Data Types
One of the basic rules concerning
programming is that no routine should
ever exceed a page.
This is accomplished by breaking the
program down into modules.
Each module is a logical unit and does a
specific job
lists, sets, and graphs, along with their
operations, can be viewed as abstract
data types
Advantages of ADTs
It is much easier to debug small routines
than large routines.
It is easier for several people to work on a
modular program simultaneously.
A well-written modular program places
certain dependencies in only one routine,
making changes easier.
Written once in the program, and any
other part of the program on the ADT can
do so by calling the appropriate function
The List ADT
We will deal with a general list of the
form a1, a2, a3, . . . , an. We say that the
size of this list is n. We will call the special
list of size 0 a null list.
For any list except the null list, we say
that ai+l follows (or succeeds) ai (i < n) and
that ai-1 precedes ai (i > 1). The first
element of the list is a1, and the last
element is an.
Operations on the List ADT
print_list()
make_null()
find()
insert()
delete()
Simple Array Implementation of Lists
Obviously all of these instructions can be
implemented just by using an array
Usually this requires a high over-estimate,
which wastes considerable space
print_list and find to be carried out in
linear time
However, insertion and deletion are
expensive
simple arrays are generally not used to
implement lists.
The Polynomial ADT
If most of the coefficients ai are nonzero,
we can use a simple array to store the
coefficients.
This is adequate for dense polynomials,
where most of the terms are present
if p1(x) = 10x1000 + 5x14 + 1 and p2(x) =
3x1990 - 2x1492 + 11x + 5
Linked list representations of two
polynomials
typedef struct node *node_ptr;
struct node
{
int coefficient;
int exponent;
node_ptr next;
};
typedef node_ptr POLYNOMIAL;
/* keep nodes sorted by exponent */
Linked list representations of
two polynomials
Linked list representations of
two polynomials
struct Node
{
int coeff;
int pow;
struct Node* next;
};
Creating Polynomials
void create_node(int x, int y, struct Node** temp)
{
struct Node *r, *z;
z = *temp;
if (z == NULL) {
r = (struct Node*)malloc(sizeof(struct Node));
r->coeff = x;
r->pow = y;
*temp = r;
r->next = (struct Node*)malloc(sizeof(struct Node));
r = r->next;
r->next = NULL;
}
Creating Polynomials
else {
r->coeff = x;
r->pow = y;
r->next = (struct Node*)malloc(sizeof(struct
Node));
r = r->next;
r->next = NULL;
}
}
Adding Polynomials
void polyadd (struct Node* poly1, struct Node*
poly2, struct Node* poly)
{
while (poly1->next && poly2->next) {
// If power of 1st polynomial is greater then 2nd,
// then store 1st as it is and move its pointer
if (poly1->pow > poly2->pow) {
poly->pow = poly1->pow;
poly->coeff = poly1->coeff;
poly1 = poly1->next;
}
Adding Polynomials
else if (poly1->pow < poly2->pow)
{
poly->pow = poly2->pow;
poly->coeff = poly2->coeff;
poly2 = poly2->next;
}
Adding Polynomials
else {
poly->pow = poly1->pow;
poly->coeff = poly1->coeff + poly2->coeff;
poly1 = poly1->next;
poly2 = poly2->next;
}
Radix Sort
Input: 64, 8, 216, 512, 27, 729, 0, 1, 343, 125
Pass 1: 0, 1, 512, 343, 64, 125, 216, 27, 8, 729
Pass 2: 0, 1, 8, 512, 216, 125, 27, 729, 343, 64
Pass 3: 0, 1, 8, 27, 64,125, 216, 343, 512, 729.
Radix Sort Pass 1
Radix Sort Pass 2
Radix Sort Pass 3
Cursor Implementation of Linked
Lists
typedef unsigned int node_ptr;
struct node
{
element_type element;
node_ptr next;
};
typedef node_ptr LIST;
typedef node_ptr position;
struct node CURSOR_SPACE[ SPACE_SIZE ];