Unit 3
Unit 3
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
Unit 3
Stack ADT
• A Stack is an Abstract Data Type with a pre-defined size where it store the elements of a limited
size.
• Stack is a type of linear data structure that follows LIFO (Last in First Out) or in FILO ( First in
Last Out) order.
• It is an ordered collection of elements in which the insertion and deletion of an element done in
one end known as top of the stack.
• isFull() - It is used to check whether stack is full or not. It is called before every insertion.
• isEmpry() -Is used to check whether stack is empty or not. It is called before every deletion.
• push(item)- Is used to push an ‘item’ into the stack.
• pop() - Is used to delete an element from top of the stack.
• peek() -Is is used to extract the ‘top most’ element of the stack
• size() - Is used to get number of elements in the stack.
•
Example
• Let consider 10,20,30,40,50 are stack elements.
• Stack Representation
Top
Push operation
Unit 1 Page 1
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
POP Operation
Peek Operation
• Peek operations returns the topmost element of the stack without removing it from the stack.
• Stack states Underflow conditions when try to return the topmost element if the stack is already
empty.
Display Operation
• Display function display the stack element.
• When the stack has an element it prints all the element sequentially.
• When there is no element in the stack, it displays underflow condition.
• In stack using array ,the elements can be pushed(insert) and popped(delete) only at one end we
call it as “Top”.
• The top pointer will be -1 if there is no elements found in the stack.
• Also, if the stack is full the top pointer will be in the max size of the array.
Condition to check
1. Before PUSH:
If(!Stackfull)//elements cant be pushed if it is full
{Push element}
2.Before POP:
If(!Stackempty)//elements cant be popped because no elements in the stack
{Pop element}
Unit 3 Page 2
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
Peek Operation
• This is a operation used to return the top pointer value without deleting the position.
• Before performing the Peek operation, the condition of stack empty is checked(top=-1). So that
the empty stack will not any element to be displayed.
• The stack using array is simple and easy structure but the size of the array is fixed and it has to
be declared earlier, which could not be predicted at earlier stage.
• So in order to overcome this problem, stack using liked list is used aka. Linked stack.
• Space Complexity is O(n) and Time Complexity is O(1)
Peek Algorithm
Step 1: If top==-1
Print“stack is Empty” //Checks for Underflow
break;
Step 2: Else Return Stack[top]
Step 3: Stop
Unit 3 Page 3
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
Unit 3 Page 4
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
Display
• Nodes in the stack displayed in the form of stack.
• Follow the steps to display the stack elements,
• Assign the head pointer to temporary pointer (temp)
• Move the temporary pointer(temp) through all the nodes of the list,
• and print the value field of every node.
Infix Notation
• When the operator is written in between the operands, then it is known as infix notation.
• Operand1 operator Operand2
• Example
• A+B
• (a + b) * (c + d)
• Operand does not have to be always a constant or a variable; it can also be an expression.
Postfix Notation
• When the operator is written after the operands, then it is known as postfix notation.
• It is also known as Reverse Polish Notation
• Operand1 operator Operand2
• Example
• AB +
• ab+ cd+ *
• Operator precedence - This refers to the priority given to each operator in an expression.
• In Arithmetic * / has equal precedence and it has higher precedence than + - ,where + - are
equal.
• Associativity - If two operators have the same precedence, associativity is used to determine
the order of evaluation.
• Associativity determines the evaluation of expression either from Left to Right or Right to Left.
• It executes when have two or more operators of same precedence.
Unit 3 Page 5
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
• If the scanned character is an operator and if the stack is empty Push the character to stack.
• If the scanned character is an Operand and the stack is not empty, compare the precedence of the
character with the element on top of the stack (topStack).
• If the operator has higher precedence than the top of the stack, then push the operator on to the
stack.
• If the operator has lower or equal precedence than the top of the stack, then pop out and
appending it to the postfix expression.
• Repeat this step till all the characters are scanned.
• If scanned character is Right parenthesis, then pop character from stack until left parenthesis
reached on the stack.
• If all characters are scanned but stack is not empty, then Pop the operator from the stack and in
postfix expression. Repeat until the stack becomes empty.
Postfix notation
• The Postfix notation is used to represent algebraic expressions.
• The expressions written in postfix form are evaluated faster compared to infix notation as
parenthesis is not required in postfix.
Example:
• Input Expression: 2 5 3 6 + * * 15 / 2 –
• Output Expression: 16
Unit 3 Page 6
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
• When the end of the expression is reached, the stack must be empty; otherwise one or more opening
parenthesis does not have corresponding closing parenthesis. So the expression is invalid.
Algorithm
Step 1: Create character array which holds the expression.
Step 2: Check for the left parenthesis in the given expression traversing left to right side of the given
expression .
• If left parenthesis ‘{‘ or’(‘or ‘[‘ hit then push that parenthesis in the stack.
• Pop the open parenthesis after every Closed parenthesis hit’ )’ or ‘] or ‘]’)
• If the stack left with any open parenthesis at the end of the expression means “the parenthesis is not
balanced”.
Unit 3 Page 7
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
• A function call is said to be nested function call when it is defined inside another function which
can be called from outside with another function.
• The nested function can be called by extending the scope from outside to another function by
passing address.
• Stack data structure is used to manage nested function call.
• Consider an example ,Inside a main function, the function X is invoked , in the definition of the
X function, Function Y is called, in the definition of Y the function Z is invoked and the definition
of Z function the function C is called and B is called in the function C. So the processing of X is
get holds till Y processing is done but Y execution depends on Z function which execution is
also waiting for the C. Similarly C depends on the B execution.
• So when function B is executed the function call returns back to C ,when C is completed call
returns to Z,Z completes its execution it returns back to Y then completing it execution returns
to A.
• So the First executed function will be completed at last which is last in first out behavior LIFO
Unit 3 Page 8
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
Unit 3 Page 9
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
Recursion is a process in which a problem is defined in terms of itself. In ‘C’ it is possible to call a
function from itself. Functions that call themselves are known as recursive functions, i.e. a statement
within the body of a function calls the same function.
Example:
void main()
{ ……………………… /* Some statements*/
fun1(); ……………………… /* Some statements */
}
void fun1()
{ ……………………… /* Some statements */
fun1(); /*RECURSIVE CALL*/
……………………… /* Some statements */
}
Here the function fun1() is calling itself inside its own function body, so fun1() is a recursive function.
When main() calls fun1(), the code of fun1() will be executed and since there is a call to fun1()
insidefun1(), again fun1() will be executed. It looks like the above program will run up to infinite times
but generally a terminating condition is written inside the recursive functions which end this recursion.
The following program (which is used to print all the numbers starting from the given number to 1 with
successive decrement by 1) illustrates this:
void main()
{
int a;
printf(“Enter a number”);
scanf(“%d”,&a);
fun2(a);
}
int fun2(int b)
{ printf(“%d”,b);
b--;
if(b>=1) /* Termination condition i.e. b is less than 1*/
{
fun2(b);
}
}
How to write a Recursive Function? Before writing a recursive function for a problem its necessary to
define the solution of the problem in terms of a similar type of a smaller problem. Two main steps in
writing recursive function are as follows:
(i). Identify the Non-Recursive part(base case) of the problem and its solution(Part of the problem whose
solution can be achieved without recursion).
(ii). Identify the Recursive part(general case) of the problem(Part of the problem where recursive call
will be made).
Identification of Non-Recursive part of the problem is mandatory because without it the function will
keep on calling itself resulting in infinite recursion.
How control flows in successive recursive calls?
Flow of control in successive recursive calls can be demonstrated in following example: Consider the
following program which uses recursive function to compute the factorial of a number. In the above
program if the value entered by the user is 1 i.e.n=1, then the value of n is copied into m. Since the value
of m is 1 the condition ‘if(m==1)’ is satisfied and hence 1 is returned through return statement i.e.
factorial of 1 is 1. When the number entered is 2 i.e. n=2, the value of n is copied into m. Then in function
fact(), the condition ‘if(m==1)’ fails so we encounter the statement a=m*fact(m-1); and here we meet
void main()
Unit 3 Page 10
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
{
int n,f;
printf(“Enter a number”);
scanf(“%d”,&n);
f=fact(a);
printf(“Factorial of %d is %d”,n,f);
}
int fact(int m)
{
int a;
if (m==1)
return (1);
else a=m*fact(m-1);
return (a);
}
Unit 3 Page 11
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
/* N = Number of disks
Beg, Aux, End are the pegs */
Tower(N, Beg, Aux, End)
Begin
if N = 1 then
Print: Beg --> End;
else
Call Tower(N-1, Beg, End, Aux);
Print: Beg --> End;
Call Tower(N-1, Aux, Beg, End);
endif
End
Queue is a linear data structure in which the insertion and deletion operations are performed at
two different ends. In a queue data structure, adding and removing elements are performed at two
different positions. The insertion is performed at one end and deletion is performed at another end. In a
queue data structure, the insertion operation is performed at a position which is known as 'rear' and the
deletion operation is performed at a position which is known as 'front'. In queue data structure, the
insertion and deletion operations are performed based on FIFO (First In First Out) principle.
Fron Rear
t
In a queue data structure, the insertion operation is performed using a function called "enQueue()" and
deletion operation is performed using a function called "deQueue()".
Common Queue Operations
● enqueue() – Insert an element at the end of the queue.
● dequeue() – Remove and return the first element of the queue, if the queue is not empty.
● peek() – Return the element of the queue without removing it, if the queue is not empty.
● size() – Return the number of elements in the queue.
● isEmpty() – Return true if the queue is empty, otherwise return false.
● isFull() – Return true if the queue is full, otherwise return false.
Unit 3 Page 12
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
To implement a queue using array, create an array arr of size n and take two variables front and rear both
of which will be initialized to 0 which means the queue is currently empty. Element rear is the index up
to which the elements are stored in the array and front is the index of the first element of the array. Now,
some of the implementation of queue operations are as follows:
1. Enqueue: Addition of an element to the queue. Adding an element will be performed after checking
whether the queue is full or not. If rear < n which indicates that the array is not full then store the element
at arr[rear] and increment rear by 1 but if rear == n then it is said to be an Overflow condition as the
array is full.
1. Dequeue: Removal of an element from the queue. An element can only be deleted when there is
at least an element to delete i.e. rear > 0. Now, element at arr[front] can be deleted but all the
remaining elements have to shifted to the left by one position in order for the dequeue operation to
delete the second element from the left on another dequeue operation.
2. Front: Get the front element from the queue i.e. arr[front] if queue is not empty.
3. Display: Print all element of the queue. If the queue is non-empty, traverse and print all the
elements from index front to rear.
Unit 3 Page 13
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
Enqueue Operation:
void Enqueue(int data)
{
// check queue is full or not
if (capacity == rear) {
printf("\nQueue is full\n");
return;
}
Unit 3 Page 14
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
// decrement rear
rear--;
}
return;
}
Although, the technique of creating a queue is easy, but there are some drawbacks of using this
technique to implement a queue.
o Memory wastage: The space of the array, which is used to store queue elements, can never be
reused to store the elements of that queue because the elements can only be inserted at front end
and the value of front might be so high so that, all the space before that, can never be filled.
One of the most common problem with array implementation is the size of the array which requires
to be declared in advance. Due to the fact that, the queue can be extended at runtime depending upon the
problem, the extension in the array size is a time taking process and almost impossible to be performed
at runtime since a lot of reallocations take place. Due to this reason, we can declare the array large
enough so that we can store queue elements as enough as possible but the main problem with this
declaration is that, most of the array slots (nearly half) can never be reused. It will again lead to memory
wastage.
The storage requirement of linked representation of a queue with n elements is o(n) while the time
requirement for operations is o(1).
In a linked queue, each node of the queue consists of two parts i.e. data part and the link part. Each
element of the queue points to its immediate next element in the memory.
In the linked queue, there are two pointers maintained in the memory i.e. front pointer and rear
pointer. The front pointer contains the address of the starting element of the queue while the rear pointer
contains the address of the last element of the queue.
Unit 3 Page 15
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
Insertion and deletions are performed at rear and front end respectively. If front and rear both are
NULL, it indicates that the queue is empty
Node Creation:
struct Node
{
int data;
struct Node *next;
};
Enqueue Operation:
Dequeue Operation:
void dequeue ()
{
if(front == NULL)
printf("\nQueue is Empty!!!\n");
Unit 3 Page 16
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
else{
struct Node *temp = front;
front = front -> next;
free(temp);
}
}
Circular Queue
Circular Queue is a linear data structure in which first position of the queue is connected with last
position of the queue.
In other words, the queue is considered as a circular queue when the positions 0 and MAX-1 are adjacent.
It is also referred as RING BUFFER.
Principle Used: FIFO (First In First Out) (First entered element is processed first) is used for performing
the operation.
Operations Involved
• Enqueue- is the process of inserting an element in REAR end
• Dequeue – is the process of removing elements from FRONT end
Variables Used
• MAX- Number of entries in the array
• Front – is the index of front queue entry in an array (Get the front item from queue)
• Rear – is the index of rear queue entry in an array. (Get the last item from queue)
If queue is full, display the queue is full else we can insert an element by incrementing rear pointer.
Unit 3 Page 17
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
ATM is the best example for the circular queue. It does the following using circular queue
1. ATM sends request over private network to central server
2. Each request takes some amount of time to process.
3. More request may arrive while one is being processed.
4. Server stores requests in queue if they arrive while it is busy.
5. Queue processing time is negligible compared to request processing time.
Priority Queue
Priority Queue is an abstract data type that is similar to a queue, and every element has some priority
value associated with it. The priority of the elements in a priority queue determines the order in which
elements are served (i.e., the order in which they are removed)
Properties of Priority Queue
• Every item has a priority associated with it.
• An element with high priority is dequeued before an element with low priority.
• If two elements have the same priority, they are served according to their order in the queue.
Unit 3 Page 18
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
Step 1:
• The set sptSet is initially empty and distances assigned to vertices are {0, INF, INF, INF, INF,
INF, INF, INF} where INF indicates infinite.
• Now pick the vertex with a minimum distance value. The vertex 0 is picked, include it in sptSet.
So sptSet becomes {0}. After including 0 to sptSet, update distance values of its adjacent
vertices.
Unit 3 Page 19
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
• Adjacent vertices of 0 are 1 and 7. The distance values of 1 and 7 are updated as 4 and 8.
Step 2:
• Pick the vertex with minimum distance value and not already included in SPT (not in sptSET).
The vertex 1 is picked and added to sptSet.
• So sptSet now becomes {0, 1}. Update the distance values of adjacent vertices of 1.
• The distance value of vertex 2 becomes 12.
Step 3:
• Pick the vertex with minimum distance value and not already included in SPT (not in sptSET).
Vertex 7 is picked. So sptSet now becomes {0, 1, 7}.
• Update the distance values of adjacent vertices of 7. The distance value of vertex 6 and 8 becomes
finite (15 and 9 respectively).
Step 4:
Pick the vertex with minimum distance value and not already included in SPT (not in sptSET). Vertex 6
is picked. So sptSet now becomes {0, 1, 7, 6}.
Update the distance values of adjacent vertices of 6. The distance value of vertex 5 and 8 are updated.
Prims algorithm
• Create a set mstSet that keeps track of vertices already included in MST.
• Assign a key value to all vertices in the input graph. Initialize all key values as INFINITE.
Assign the key value as 0 for the first vertex so that it is picked first.
• While mstSet doesn’t include all vertices
• Pick a vertex u which is not there in mstSet and has a minimum key value.
• Include u in the mstSet.
• Update the key value of all adjacent vertices of u. To update the key values, iterate through all
adjacent vertices. For every adjacent vertex v, if the weight of edge u-v is less than the previous
key value of v, update the key value as the weight of u-v
• Step 1: The set mstSet is initially empty and keys assigned to vertices are {0, INF, INF, INF, INF,
INF, INF, INF} where INF indicates infinite. Now pick the vertex with the minimum key value.
The vertex 0 is picked, include it in mstSet. So mstSet becomes {0}. After including it to mstSet,
update key values of adjacent vertices. Adjacent vertices of 0 are 1 and 7. The key values of 1
and 7 are updated as 4 and 8. Following subgraph shows vertices and their key values, only the
vertices with finite key values are shown. The vertices included in MST are shown in green color.
Unit 3 Page 20
21CSC201J – Data Structures and Algorithms Department & Semester – CSE / III Sem / II Year
• Step 2: Pick the vertex with minimum key value and which is not already included in the MST (not
in mstSET). The vertex 1 is picked and added to mstSet. So mstSet now becomes {0, 1}. Update
the key values of adjacent vertices of 1. The key value of vertex 2 becomes 8.
• Step 3: Pick the vertex with minimum key value and which is not already included in the MST (not
in mstSET). We can either pick vertex 7 or vertex 2, let vertex 7 is picked. So mstSet now
becomes {0, 1, 7}. Update the key values of adjacent vertices of 7. The key value of vertex 6 and
8 becomes finite (1 and 7 respectively).
• Step 4: Pick the vertex with minimum key value and not already included in MST (not in mstSET).
Vertex 6 is picked. So mstSet now becomes {0, 1, 7, 6}. Update the key values of adjacent
vertices of 6. The key value of vertex 5 and 8 are updated.
• Step 5: Repeat the above steps until mstSet includes all vertices of given graph. Finally, we get the
following graph.
Unit 3 Page 21