c Programming and Data Structures - Unit III Notes - Copy
c Programming and Data Structures - Unit III Notes - Copy
Data Structure
A data structure is a storage that is used to store and organize data.
It is a way of arranging data on a computer so that it can be accessed and
updated efficiently.
Classification of Data Structure:
Linear data structure: Data structure in which data elements are arranged
sequentially
Static data structure: Static data structure has a fixed memory size.
Example : Array
Dynamic data structure: In dynamic data structure, the size is not
fixed. It can be randomly updated during the runtime. Example :
stack,queue
Non Linear data structure: Data structure in which data elements are
arranged in hierarchical order. Example: Trees and Graph
Application 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
List ADT :
List is the group of elements and its general form is A1, A2, A3,…….AN
The size of the list is N.
The size of empty list is ‘0’.
The element Ai+1 follows Ai and the element Ai-1 precedes Ai.
The position of the element is i.
Operations on List
1.Insertion
2.deletion
3.findkth element
4.print list
Implementation
The List can be implemented in three ways
1.Array implementation
2.Linked list implementation
Array implementation
An array is a collection of similar data elements.
These data elements have the same data type.
The elements of the array are stored in consecutive memory locations and are
referenced by an index (also known as the subscript).
Insertion Operation:
Insertion operation inserts a new element to the list in the specified location.
If there is an element at the specified location, then the elements from the
specified location to the end are moved forward one by one, starting from the
last element.
This makes the empty place at the specified location.
The new element is now inserted into the specified location.
The size of the list is also increased into ‘n+1’ after the insertion of the
element.
Example:
List a, n=6
Index 0 1 2 3 4 5 6 7 8 9
Element 55 35 26 78 63 49 - - - -
Insert(18,3)
Index 0 1 2 3 4 5 6 7 8 9
Element 55 35 26 78 63 49 - - - -
a[6]=a[5]
Index 0 1 2 3 4 5 6 7 8 9
Element 55 35 26 78 63 - 49 - - -
a[5]=a[4]
Index 0 1 2 3 4 5 6 7 8 9
Element 55 35 26 78 - 63 49 - - -
a[4]=a[3]
Index 0 1 2 3 4 5 6 7 8 9
Element 55 35 26 - 78 63 49 - - -
a[3]=new
Index 0 1 2 3 4 5 6 7 8 9
Element 55 35 26 18 78 63 49 - - -
List a, n=7
Declaration:
int a[20];
void insert(int a[],int n,int pos);
int delete(int a[],int n, int pos)
void printlist(int n,int a[])
Algorithm to insert an element in to the List
void insert(int a[],int n,int x,int pos)
{
int i;
if(n==sizeof(a)
{
printf(“the list is full cant insert”);
return;
}
else
{
for(i=n-1;i>=pos;i--)
{
a[i+1]=a[i];
}
a[pos]=x;
n=n+1;
}
}
Deletion:
Index 0 1 2 3 4 5 6 7 8 9
Element 55 35 26 78 63 49 - - - -
Delete(2)
Index 0 1 2 3 4 5 6 7 8 9
Element 55 35 - 78 63 49 - - - -
a[2]=a[3]
Index 0 1 2 3 4 5 6 7 8 9
Element 55 35 78 - 63 49 - - - -
a[3]=a[4]
Index 0 1 2 3 4 5 6 7 8 9
Element 55 35 78 63 - 49 - - -
a[4]=a[5]
Index 0 1 2 3 4 5 6 7 8 9
Element 55 35 78 63 49 - - - -
List a, n=5
Algorithm to delete an element from the List
int delete(int a[],int n, int pos)
{
int i,d;
if(n==0)
{
printf(“list is empty and cannot delete”);
return;
}
else
{
d=a[pos];
for(i=pos;;i<=n-1;i++)
{
a[i]=a[i+1];
}
n=n-1;
return d;
}
Print List:
It is used to print the elements of the list one by one starting from the element
at index ‘0’ to index ‘n-1’.
NULL
Node definition:
struct node
{
int data;
struct node *next;
};
Declaration of Node:
struct node *head, *temp;
Allocating Space for Node:
temp = (struct node *)malloc(sizeof(struct node));
Operations on Singly Linked List:
1. Insertion
2. Deletion
3. Traversal
1. Insertion
The insertion into a singly linked list can be performed at different positions.
1. Insert at the beginning
2. Insert at the end
3. Insert after specified node
1. Insert at the beginning:
Inserting any element at the front of the list
The new node is the first node.
Initially first element is the header node.
After the insertion of new element, the new element becomes the first element in the
list
After Insertion
Insert 20 at the beginning of the list.
Method declaration:
struct node *insertatend(struct node *head, int x)
struct node * insertatposition(struct node *head, int x, int pos)
struct node * insertatposition(struct node *head, int x, int pos)
struct node *deleteatend(struct node *head);
struct node *deleteatbeg(struct node *head);
struct node *deleteatposition(struct node *head,int pos);
void display(struct node *head);
Algorithm to insert an element at the end of the List
struct node *insertatend(struct node *head, int x)
{
struct node *newnode,*temp;
newnode=(struct node *)malloc(sizeof(struct node));
newnode->data=x;
temp=head;
if(head==null)
{
newnode->next=null;
head=newnode;
}
else
{
while(temp->next!=null)
{
temp=temp->next;
}
temp->next=newnode;
newnode->next=null;
}
return head;
}
3. Insert after specified node
Insert the element after the specified node of the linked list.
Traverse the list to find the specified node.
After Insertion:
Insert 20 after 10
Algorithm to insert an element at the specified location of the List
struct node * insertatposition(struct node *head, int x, int pos)
{
struct node *newnode,*temp;
newnode=(struct node *)malloc(sizeof(struct node));
newnode->data=x;
temp=head;
if(head==null)
{
newnode->next=null;
head=newnode;
}
else
{
while(temp->next!=null)
{
if(temp->data==pos)
{
newnode->next=temp->next;
temp->next=newnode;
}
temp=temp->next;
}
}
return head;
}
2. Deletion
The Deletion of a node from a singly linked list is performed at different positions.
1. Deletion at beginning
2. Deletion at the end
3. Deletion after specified node
1. Deletion at beginning
This operation deletes the first element of the list.
The first node is head node.
After the deletion of the first node, the new node is the head node.
Algorithm to delete an element at beginning of the List
strtuct node *deletefirst(struct node *head)
{
struct node *temp;
temp=head;
if(head==null)
{
printf(“the list is empty”);
}
else
{
head=temp->next;
free(temp);
}
return head;
}
Before deletion
head
After Deletion
head
Before Deletion
head
Head
Head
Delete 20
After Deletion
Head
struct node
{
struct node *prev;
int data;
struct node *next;
};
Node definition:
struct node
{
int data;
struct node *next;
};
Application of List
Polynomial operations (Addition, subtraction and Multiplication)
Used in radix and bubble sorting
Used to implement all linear and non-linear data structures.
Stack ADT:
A stack is a linear data structure
In stack the elements are added and removed only from one end, called as top.
A stack is a LIFO (Last in first out) data structure
The elements that was inserted last is the first one to be accessed.
The operations performed are push and pop.
Implementation:
A stack can be implemented using I) Array and ii) Linked List
Array Representation of stacks:
In the computer memory, stacks can be represented as a linear array.
Every stack has a variable called TOP .
TOP is the position where the elements are added or deleted.
Another variable used is MAX, is the maximum number of elements
that the stack can store.
If TOP=0 then the stack is empty and if TOP=MAX-1 then the stack is full.
10 20 30 40 50 60 70
0 1 2 3 4 5 6 7 8 9
Here the value for Max = 10 , TOP = 6
Operations on a stack:
A stack has three basic operations: PUSH, POP ,and display the topmost
element.
PUSH Operation:
The push operation is the process of inserting a new element to the top
of the stack.
For every push operation the top is incremented by 1.
Top 20
Top 10
10
Top 30
Top 20
20 Top 10
10 10
Initial Stack After deleting 30 After the deletion of 20
Array Implementation of Stack :
Algorithm:
Declaration for array representation of stacks
#define max 10
Int st[max],top=-1;
void push(int st[],intval)
int pop(int st[])
int displaytop(intst[]);
void display(int st[])
int isempty()
int isfull()
Routine to check whether the stack is empty
int isempty()
{
if(top == -1)
return(1);
else
return(0);
}
Routine to check whether the stack is Full
int isfull()
{
if(top==max-1)
return(1);
else
return(0)
}
Routine to Push an element onto a stack
void push(int st[],int val)
{
if(isfull())
printf(“stack is full”)
else
{
top=top+1;
st[top]=val;
}
}
Routine to Pop an element from the stack
int pop(int st[])
{
if(isempty())
{
printf( “ stack is empty”);
}
else
{
x=st[top]
top=top--;
}
return(x)
}
Routine to return the top element of the stack
int displaytop(int st[])
{
if(isempty())
{
printf( “stack is empty”);
}
else
return st[top];
}
Routine to display the elements of the stack
void display(int st[])
{
if(isempty())
{
Printf( “stack is empty”);
}
else
{
for(i=0;i<=top;i++)
printf “%d”,(st[i]));
}
}
Linked Representation of stack:
Linked List:
Linked List is a linear data structure.
Linked list elements are not stored at a contiguous location.
The elements are linked using pointers.
The linked list is a collection of nodes.
Each node stores the data and the address of the next node.
Implementation:
Declaration of Node:
struct node *top, *temp;
Algebraic expression:
There are three different ways to representing the algebraic expression
They are :
1) Infix notation
2) Postfix or reverse polish notation
3) Prefix or polish notation
Infix notation:
In Infix notation the operator is placed in between the operands
a+b
Postfix or reverse polish notation:
In the postfix notation, the operator is placed after the operands.
ab+
Prefix notation or polish notation:
In the postfix notation, the operator is placed before the operands.
+ab
Explain the need for infix and postfix expression
It is easy to write the infix expression.
But the computer find it difficult to parse because it may needs lot of
information to evaluate the expression.
The computers work more efficiently with prefix and postfix notation.
The computers first convert the infix expression into postfix notation and then
evaluate the postfix expression.
Example:
Show the simulation using stack for the following expression to convert infix to
postfix :
p*q+(r-s/t)
Consider the following infix expression
P * q + ( r – s / t)
Scanned Stack Output Description
Character
P p P is an operand, place it on to the output
* * *is an operator place it onto the stack
Q * Pq q is an operand, place it on to the output
+ + P q * Incoming operator : +
Operator at the top of the stack : *
Compare if( priority of ‘ * ‘ > priority of ‘ + ‘)
then pop * and push +
( +( If the character is a left parenthesis, push it onto
the stack
R +( P q *r r is an operand, place it on to the output
- +(- P q * r Compare if( priority of ‘(‘ > priority of ’ – ‘) –
false , so push -
S +(- P q * r s s is an operand, place it on to the output
/ +(-/ P q * r s Compare if priority of ‘ – ‘ > priority of ‘ / ‘,
false , so push /
T +(-/ P q * r s t t is an operand, place it on to the output
) + P q * r s t / - If the character is a right parenthesis then pop
all the operators from the stack till it encounters
left parenthesis
P q * r s t / - Pop the remaining operators from the stack
+
Postfix Expression:
Pq *r s t / - +
Example
Show the simulation using stack for the following expression:
Infix Notation: 12 + 3 *14 –(5*16) + 7
postfix notation : 12 3 14 * + 5 16 * 7 + -
Scanned Stack Output Description
Character
12 12 If the character is an operand , push its
associated value onto the stack. Push ’12 ‘
3 * 14 = 42
+ 54 12 + 42 = 54
5 54 5 If the character is an operand , push its
associated value onto the stack.Push ‘ 5 ‘
16 54 5 16 If the character is an operand , push its
associated value onto the stack.Push ‘ 16 ‘
* 54 80 5 * 16= 80
7 54 80 7 If the character is an operand , push its
associated value onto the stack.Push ‘ 7 ‘
+ 54 87 80 + 7= 87
- - 33 54 – 87 = -33
Queue ADT:
A queue is a Linear data structure.
A queue is a FIFO(First in First Out) Data structure
The element that was inserted first is the first one to be taken out.
The elements inserted at one end called the rear
The elements removed from the other end called the front.
Front Rear
10 2 30 40 50 60 70
0 1 2 3 4 5 6 7 8 9
Here front = 0 and rear = 6
Operations on Queue:
1) Enqueue – The process of inserting an element in a queue
2) Dequeue – The process of deleting an element from a queue.
Implementation of Queues:
Queue can be implemented using 1) Array and
2) Linked List
Array Implementation:
Queues can be easily implemented using array. Every queue has front and rear
variables to point the position of insertion and deletion respectively.
The initial value of front = rear = -1
Enqueue :
To insert an element into the queue,
First the rear is incremented by 1 ,
Then the value is stored at the position of
rear .
For the first insertion both front and rear will be incremented.
Before inserting an element in the queue, check for”queue full condition” and
“queue empty “condition.
Dequeue:
To delete an element from the queue, the value for front is incremented.
Before deleting an element, we must check for ”queue empty “ condition.
The queue after the deletion of 10
front Rear
2 30 40 50 60 70 80
0 1 2 3 4 5 6 7 8 9
Now the value for front=1 and rear= 7
Circular Queue is a linear data structure in which the operations are performed based
on FIFO (First In First Out) principle and the last position is connected back to the
first position to make a circle.