Dsu Nores
Dsu Nores
A real-world stack allows operations at one end only. For example, we can place or remove a card or
plate from the top of the stack only. Likewise, Stack ADT allows all data operations at one end only. At
any given time, we can only access the top element of a stack.
This feature makes it LIFO data structure. LIFO stands for Last-in-first-out. Here, the element which is
placed (inserted or added) last, is accessed first. In stack terminology, insertion operation is
called PUSH operation and removal operation is called POP operation.
Stack Declaration:
#define size 10
struct stack {
int s[size];
int top;
}st;
Stack Representation
The following diagram depicts a stack and its operations –
A stack can be implemented by means of Array, Structure, Pointer, and Linked List. Stack can either be
a fixed size one or it may have a sense of dynamic resizing. Here, we are going to implement stack using
arrays, which makes it a fixed size stack implementation.
Stack data structure can be implemented in two ways. They are as follows...
1. Using Array
2. Using Linked List
When stack is implemented using array, that stack can organize only limited number of elements. When
stack is implemented using linked list, that stack can organize unlimited number of elements.
Basic Operations
Stack operations may involve initializing the stack, using it and then de-initializing it. Apart
from these basic stuffs, a stack is used for the following two primary operations −
To use a stack efficiently, we need to check the status of stack as well. For the same purpose, the
following functionality is added to stacks −
At all times, we maintain a pointer to the last PUSHed data on the stack. As this pointer always
represents the top of the stack, hence named top. The top pointer provides top value of the stack without
actually removing it.
First we should learn about procedures to support stack functions −
isfull()
Algorithm of isfull() function −
Example
bool isfull() {
if(top == MAXSIZE)
return true;
else
return false;
}
Stack Overflow: if the stack is full and we are trying to add one more element into the stack tjen that
situation is called as Stack Overflow
isempty()
Algorithm of isempty() function −
Example
bool isempty() {
if(top == -1)
return true;
else
return false;
}
Stack underflow: if the stack is empty and we are trying to delete the element from empty stack then
that situation is called as Stack underflow
• Step 3 − If the stack is not full, increments top to point next empty space.
• Step 4 − Adds data element to the stack location, where top is pointing.
Implementation of this algorithm in C, is very easy. See the following code for push operation−
Example
Pop Operation
Accessing the content while removing it from the stack, is known as a Pop Operation. In an array
implementation of pop() operation, the data element is not actually removed, instead top is decremented
to a lower position in the stack to point to the next value. But in linked-list implementation, pop()
actually removes data element and de-allocates memory space.
• Step 3 − If the stack is not empty, accesses the data element at which top is pointing.
• Step 4 − Decreases the value of top by 1.
Application of Stacks
1) Reversing the list
i. The application of the stack is it prints any given series of
numbers whether sorted or unsorted in reverse order.
ii. As the stack follows Last In First Order (LIFO), it gives the
series of number in reverse order.
iii. Given below is the program to print the stack.
Example for Reversing the list : WAP to PUSH and POP the elements on to the
stack, without using functions
#include<stdio.h>
void main()
{
int stack[5], top = -1;
while (top <5)
{
top++;
printf (“\nenter the element for the stackè”);
scanf (“%d”, &stack[top]);
}
while (top!=0)
{
printf(“\nthe popped element isè %d”, st[top]);
top = top -1;
}
}
OUTPUT:
enter the element for the stackè10
enter the element for the stackè20
enter the element for the stackè30
enter the element for the stackè40
enter the element for the stackè50 the
popped element isè50
the popped element isèè40
the popped element isè30
the popped elementè is 20
the popped element is 10
2) Polish Notation
i. Infix, Postfix and Prefix notations are three different but
equivalent ways of writing expressions known as Polish
notation.
ii. It is easiest to demonstrate the differences by looking at
examples of operators that take two operands.
Infix notation: X + Y
Postfix notation (also known as "Reverse Polish notation"): X Y +
Prefix notation (also known as "Polish notation"): + X Y
iii. Operators are written in-between their operands.
iv. An expression such as A * (B + C) / D is usually taken to mean
by multiplication first, then followed by division and then +.
a) Infix expression:
In this type of expression the operator is in between the operands. which means that if we take
+ operator which is a binary operator then in infix type it will be operand operator operand i.e.
infix expression: a + b where a and b are the operands and + is an operator.
b) Prefix expression:
In this type of expression the operator come first and then two operands can be placed. The way
to write the prefix expression can be
Prefix expression=operator operand operand
c) Postfix expression
In the postfix expression the operator should be written as last i.e. postfix expression = operand
operand operator
For example the infix expression a+b can be written as ab+
(A + B) * C AB+C* *+ABC
Note that the prefix and postfix forms do not make use of parenthesis as these forms are
unambiguous. The order of applying operators is unique. In the first example of postfix
expression, the operators ‘*’ and ‘+’ appear after the operands. The expression will be
evaluated by first applying the operator ‘*’ on B and C and then apply ‘+’ with a and the result.
In case of prefix form, similar order can be extracted.
Example 2: A * (B + D) / E – F * (G + H / K)
Input Stack Output
A none A
* * A
( (* A
B (* AB
+ +(* AB
D +(* ABD
) * Pop + and delete ( ABD+
/ Pop * and push / ABD+*
E / ABD+*E
- Pop / and push - ABD+E/
F - ABD+E/F
* *- ABD+E/F
( (*- ABD+E/F
G (*- ABD+E/FG
+ +(*- ABD+E/FG
H +(*- ABD+E/FGH
/ /+(*- ABD+E/FGH
K /+(*- ABD+E/FGHK
) *- Pop /+ delete ( ABD+E/FGHK/+
None Pop *- ABD+E/FGHK/+*-
3.2.2 Converting an expression from infix into prefix:
Algorithm for converting infix into prefix expression
4. If any operator comes compare the incoming operator with stack operator. If the
incoming operator priority is higher than stack operator priority push the incoming
operator.
5. If the incoming operator has less priority than the operator inside the stack then go on
popping the operator from top of the stack and print them till this condition is true and
then push the incoming operator on top of the stack.
6. If both incoming and stack operator priority are equal then push the incoming operator.
7. If the operator is ‘)’ then push the operator. Repeat the steps 3,4,5,6 for upcoming
operators till a matching ‘(‘ operator is found. then go on pop the operators from top of
the stack and delete the ‘)’ operator.
8. Let us take the example
Example 1: Convert the infix expression A + B - C into prefix expression.
Reverse expression is C-B+A
End -+ABC The input is now empty. Pop the output symbols from the
of stack until it is empty.
string
Example 2: A * (B + D) / E – F * (G + H / K)
-/*A+DE*F+G/KH
-/*A+DE*F+G/KH
Input Stack Output
( (
K ( K
/ /( K
H /( KH
+ +( KH/
G +( KH/G
) KH/G+
* * KH/G+
F * KH/G+F
- - KH/G+F*
E - KH/G+F*E
/ /- KH/G+F*E
( (/- KH/G+F*E
D (/- KH/G+F*ED
+ +(/- KH/G+F*ED
E +(/- KH/G+F*ED
) /- KH/G+F*ED+
* */- KH/G+F*ED+
A */- KH/G+F*ED+A
END OF EXPRESSION /- KH/G+F*ED+A*
- KH/G+F*ED+A*/
KH/G+F*ED+A*/-
KH/G+F*ED+A*/-
-/*A+DE*F+G/KH
3.2.3 Evaluation of Postfix Expression:
The postfix expression is evaluated easily by the use of a stack. When a number is seen, it is pushed
onto the stack; when an operator is seen, the operator is applied to the two numbers that are popped
from the stack and the result is pushed onto the stack. When an expression is given in postfix
notation, there is no need to know any precedence rules
Eg.- To evaluate the given postfix expression, let’s start with the example
10 2 8 * + 3 -
4. The next element is an operator (*), so we pop out the top two number from the stack and
perform * on the two numbers.
5. Then push the result on top of the stack.
6. The next element is a + operator, so we perform the addition on the next two elements on the
stack.
Result=23
Algorithm:
Expression: +9*26
Result: 21
3.2.5 Recursion:
The function calls itself is called as recursion. Recursion is the process of defining something in
terms of itself. For a computer language to be recursive, a function must be able to call itself.
For example, let us consider the function factorial() shown below, which computes the factorial of an
integer.
#include <stdio.h>
main()
int result; if (n == 0)
return (1);
else
return (result);
Figure1 illustrates the initial setup of towers of Hanoi. The figure 2, illustrates the final setup of
towers of Hanoi.
The rules to be followed in moving the disks from tower 1 tower 3 using tower 2 are as follows:
• Only one disk can be moved at a time.
• Only the top disc on any tower can be moved to any other tower.
• A larger disk cannot be placed on a smaller disk.
Figure : 1
Figure : 2
The towers of Hanoi problem can be easily implemented using recursion. To move the largest
disk to the bottom of tower 3, we move the remaining n – 1 disks to tower 2 and then move the
largest disk to tower 3. Now we have the remaining n – 1 disks to be moved to tower 3. This
can be achieved by using the remaining two towers. We can also use tower 3 to place any disk
on it, since the disk placed on tower 3 is the largest disk and continue the same operation to
place the entire disks in tower 3 in order.
Tower of Hanoi, is a mathematical puzzle which consists of three towers (pegs) and more than one
rings is as depicted –
(https://www.tutorialspoint.com/data_structures_algorithms/tower_of_hanoi.htm)
These rings are of different sizes and stacked upon in an ascending order, i.e. the smaller one sits over
the larger one. There are other variations of the puzzle where the number of disks increase, but the
tower count remains the same.
Tower of Hanoi puzzle with n disks can be solved in minimum 2n−1 steps. This presentation shows
that a puzzle with 3 disks has taken 23 - 1 = 7 steps.
Queue
Introduction
The queue is another abstract data structure. A physical representation of a queue is a line at the
checkout of a shop or at the bank automatic teller machine. When you join the queue you go to the
rear of the line. Customers, who have been served, move from the front of the queue. Like the stack,
the queue usually holds things of the same data type. We usually draw queues in a horizontal
direction. However, you can draw the queue vertically if you wish. The main property of the queue
ADT is that elements are added to the rear of the queue and are removed from the front of the queue.
i. A queue is a list from which items are deleted from one end (front) and into which items are
inserted at the other end (rear, or back) ii. It is like line of people waiting to purchase tickets:
iii. Queue is referred to as a first-in-first-out (FIFO) data structure.
iv. The first item inserted into a queue is the first item to leave.
Representation of a Queue:
a. Array Representation:
i. With queues two integer indexes is required, one giving the position of the front element of the
queue in the array, the other giving the position of the back element, or rather in a similar way to
stacks, the position after the back element.
ii. We add the elements from rear, and remove the elements from the front as shown in the Figure.
iii. In queue as we delete one data element, the front is incremented by one.
iv. We delete the elements from the end, known as the rear of the queue.
v. The disadvantage of using the queue is as we delete the elements, the front moves ahead, even
though the queue is empty we still cannot add the elements in the queue.
rear++;
qu[rear] = item;
}
}
void delq()
{
printf(" The removed item is %d", qu[front]);
front= front + 1;
}
void main()
{
int ch = 1,ans =0,ele,temp;
clrscr();
do
{
printf("\n 1: Add the element in the queue");
printf("\n 2: Delete the element from the queue");
printf("\n 3: Display the queue");
printf("\n 4: Exit");
printf("\n Enter your choice ");
scanf("%d",&ch);
switch(ch)
{
case 1: { if (rear<=5)
{
printf("Enter the element to be added ");
scanf("%d",&ele);
addq(ele);
break;
}
else
{
printf("Queue Full");
break;
}
}
case 2: {
4. Queue
Anuradha Bhatia 5
delq();
break;
}
case 3: { temp = front;
while (front <= rear)
{
printf("\n The element of the queue are %d", qu[front]);
front++;
}
front = temp;
break;
}
case 4: {
exit();
break;
}
}
printf(" \n Do you want to continue(1 to continue , 0 to exit) ");
scanf("%d", &ans);
} while(ans != 0);
}
OUTPUT
1: Add the element in the queue
2: Delete the element from the queue
3: Display the queue
4: Exit
Enter your choice 1
Enter the element to be added 10
Queue is empty
Do you want to continue (1 to continue, 0 to exit) 1
Types of Queue
1. Simple Queue
A simple queue is the most basic queue. In this queue, the enqueue operation takes place at the rear,
while the dequeue operation takes place at the front:
Its applications are process scheduling, disk scheduling, memory management, IO buffer, pipes, call
center phone systems, and interrupt handling.
2. Circular Queue
A circular queue permits better memory utilization than a simple queue when the queue has a
fixed size.
In this queue, the last node points to the first node and creates a circular connection. Thus, it allows us
to insert an item at the first node of the queue when the last node is full and the first node is free.
It’s also called a ring buffer:
It’s used to switch on and off the lights of the traffic signal systems. Apart from that, it can be also
used in place of a simple queue in all the applications mentioned above.
3. Priority Queue
A priority queue is a special kind of queue in which each item has a predefined priority of
service. In this queue, the enqueue operation takes place at the rear in the order of arrival of the items,
while the dequeue operation takes place at the front based on the priority of the items.
That is to say that an item with a high priority will be dequeued before an item with a low
priority.
In the case, when two or more items have the same priority, then they’ll be dequeued in the order of
their arrival. Hence, it may or may not strictly follow the FIFO rule:
Applications of queue:
i. When a resource is shared among multiple consumers. Examples include CPU scheduling,
Disk Scheduling.
ii. When data is transferred asynchronously (data not necessarily received at same rate as
sent) between two processes. Examples include IO Buffers, pipes, file IO, etc.
iii. In real life scenario, Call Center phone systems uses Queues to hold people calling them
in an order, until a service representative is free.
iv. Handling of interrupts in real-time systems.