0% found this document useful (0 votes)
112 views19 pages

Stacks and Queues Overview

The document discusses stacks and queues as linear data structures. It describes their properties including LIFO and FIFO principles. Implementation of stacks using arrays is demonstrated with push and pop operations. Applications of stacks like expression evaluation, backtracking, and reversing strings are explained.

Uploaded by

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

Stacks and Queues Overview

The document discusses stacks and queues as linear data structures. It describes their properties including LIFO and FIFO principles. Implementation of stacks using arrays is demonstrated with push and pop operations. Applications of stacks like expression evaluation, backtracking, and reversing strings are explained.

Uploaded by

zaidkhan26103
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Chapter 3 Stacks and Queues

Introduction to Stack

Stack is a linear data structure in which the insertion and deletion operations are performed
at only one end. In a stack, adding and removing of elements are performed at a single
position which is known as "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 stack, the insertion and deletion
operations are performed based on LIFO (Last In First Out) principle

● It is type of linear data structure.


● It follows LIFO (Last In First Out) property.
● It has only one pointer TOP that points the last or top most element of Stack.
● Insertion and Deletion in stack can only be done from top only.
● 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. Insertion in stack is also known as a
PUSH operation.
● Whenever we want to delete a value from the stack, then delete the top value and
decrement the top value by one. Deletion from stack is also known as POP operation
in stack.

Memory representation of stack

There are two ways to represent stacks in memory:


1. Array representation (Static data structure)
2. Linked list representation (Dynamic data structure)
Stack as an ADT:

A stack data structure can be represented as:

Using structure:
struct stack
{
int data [MAX];
int top;
} s;

Using array:

#define SIZE 10
int stack[SIZE], top = -1;
Various operations on stack that are necessary:

1) void initialize(): Initializes an empty stack. Initial value of top is set to -1.
2) int empty(): checks whether the stack is empty or not. It returns 1 when empty else 0
3) int full() : checks whether the stack is full or not. It returns 1 when full else 0
4) void push( int x): inserts element ‘x’ in stack at position pointed by the top+1.
Insertion will cause stack overflow if stack is full
5) int pop(): returns the element pointed by the top pointer. It causes stack underflow if
the stack is empty.

Condition for Stack Overflow / Stack full:

int isFull()
{
if(top == SIZE -1)
return 1;
return 0;
}

Condition for Stack Underflow/ Stack empty:

int isEmpty()
{
if(top == -1)
return 1;
return 0;
}

PUSH operation:
The process of putting a new data element onto stack is known as a Push Operation. Push
operation involves a series of steps −
Step 1 − Checks if the stack is full.
Step 2 − If the stack is full, display “stack is FULL”and exit.
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.
Step 5 − Returns success.
void push(int data) {
if(!isFull())
{
top = top + 1;
stack[top] = data;
}
else
{
printf("Could not insert data, Stack is full.\n");
}
}

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.

A Pop operation may involve the following steps −


Step 1 − Checks if the stack is empty.
Step 2 − If the stack is empty, produces an error and exit.
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.
Step 5 − Returns success.

int pop(int data) {


if(!isempty()) {
data = stack[top];
top = top - 1;
return data;
}
else
{
printf("Could not retrieve data, Stack is empty.\n");
}
}
WAP for implementation of stack using arrays

#include<stdio.h>
#include<conio.h>
#define SIZE 10
void push(int);
void pop();
void display();
int stack[SIZE], top = -1;
void main()
{
int value, choice;
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]);

}
}

Output:

***** MENU *****


1. Push
2. Pop
3. Display
4. Exit
Enter your choice: 1
Enter the value to be insert: 10

Insertion success!!!

***** MENU *****


1. Push
2. Pop
3. Display
4. Exit
Enter your choice: 1
Enter the value to be insert: 20

Insertion success!!!

***** MENU *****


1. Push
2. Pop
3. Display
4. Exit
Enter your choice: 1
Enter the value to be insert: 30

Insertion success!!!

***** MENU *****


1. Push
2. Pop
3. Display
4. Exit
Enter your choice: 2

Deleted : 30

***** MENU *****


1. Push
2. Pop
3. Display
4. Exit
Enter your choice: 3

Stack elements are:


20
10

***** MENU *****


1. Push
2. Pop
3. Display
4. Exit
Enter your choice:

Applications of Stack:

1. Expression Evaluation: Stack is used to evaluate prefix, postfix and infix


expressions.
2. Expression Conversion : An expression can be represented in prefix, postfix or infix
notation. Stack can be used to convert one form of expression to another.
i. Infix to Postfix
ii. Infix to Prefix
iii. Postfix to Infix
iv. Prefix to Infix
3. Syntax Parsing: Many compilers use a stack for parsing the syntax of expressions,
program blocks etc. before translating into low level code.
4. Backtracking: Suppose we are finding a path for solving maze problem. We choose
a path and after following it we realize that it is wrong. Now we need to go back to the
beginning of the path to start with new path. This can be done with the help of stack.
5. Parenthesis Checking : Stack is used to check the proper opening and closing of
parenthesis.
6. String Reversal : Stack is used to reverse a string. We push the characters of string
one by one into stack and then pop character from stack.
7. Function Call :Stack is used to keep information about the active functions or
subroutines.

Reversing String using Stack

Reversing string is an operation of Stack by using Stack we can reverse any string, here we
implemented a program in C - this will reverse given string using Stack.
The logic behind to implement this program:
1. Read a string.
2. Push all characters until NULL is not found - Characters will be stored in stack variable.
3. Pop all characters until NULL is not found - As we know stack is a LIFO technique, so last
character will be pushed first and finally we will get reversed string in a variable in which we
store inputted string

Code:
#include<stdio.h>
#include<conio.h>
#define SIZE 10
void push(char);
char pop();
void display();
char stack[SIZE], top = -1;
int main() {
char str[SIZE];
int i;
printf("Input a string: ");
scanf("%[^\n]s",str); /*read string with spaces*/
/*gets(str);
-can be used to read string with spaces*/
for(i=0;i<strlen(str);i++)
push(str[i]);
for(i=0;i<strlen(str);i++)
str[i]=pop();
printf("\nReversed String is: %s\n",str);
return 0; }

void push(char value){


if(top == SIZE-1)
printf("\nStack is Full!!! Insertion is not possible!!!");
else{
top++;
stack[top] = value;
printf("\nInsertion success!!!");

}
}
char pop(){
char ch;
if(top ==-1)
printf("\nStack is Empty!!! Deletion is not possible!!!");
else{
printf("\nDeleted : %c", stack[top]);
ch= stack[top];
top--;
}
return ch;
}
void display(){
if(top ==-1)
printf("\nStack is Empty!!!");
else{
int i;
printf("\nStack elements are:\n");
for(i=top; i>=0; i--)
printf("%c\n",stack[i]);

}
}

Output:
Input a string: hello

Insertion success!!!
Insertion success!!!
Insertion success!!!
Insertion success!!!
Insertion success!!!
Deleted : o
Deleted : l
Deleted : l
Deleted : e
Deleted : h
Reversed String is: olleh

Polish Notation (PN)


Polish notation is a notation form for expressing arithmetic, logic and algebraic equations. Its
most basic distinguishing feature is that operators are placed on the left of their operands. If
the operator has a defined fixed number of operands, the syntax does not require brackets
or parenthesis to lessen ambiguity
There are 3 different ways to write an algebraic expression:
● Infix form
● Prefix form
● Postfix form

Infix form: The binary operator is between the two operands.


infix-expression := (infix-expression operand infix-expression)
Examples
(3 * 7)
((1 + 3) * 2)
((1 + 3) * ( 2 - 3))

Prefix form: the operator precedes the two operands.


prefix-expression := (operand prefix-expression prefix-expression)
Examples
(* 3 7) or simply * 3 7
(* ( + 1 3) 2) or simply * + 1 3 2
( * ( + 1 3) ( - 2 3)) or simply * + 1 3 - 2 3

Postfix form: the operator is after the two operands.


postfix-expression := (operand postfix-expression postfix-expression)
Examples
(3 7 *) or simply 3 7 *
((1 3 + ) 2 *) or simply 1 3 + 2 *
((1 3 +) ( 2 3 -) * ) or simply 1 3 + 2 3 - *
Infix to Postfix:
Convert the infix expression A*(B+C*D)+E to postfix

Evaluation of Postfix Expression


4,5,6,*,+,
Evaluation of Prefix Expression

Recursion : Application of Stack

How stack applies to recursion... Every executable’s main is loaded into a program stack at
the beginning of execution.

It remains there until it completes, at which time it is popped off of the stack. If main calls a
function, that function is loaded onto the top of the stack and remains there until it is
complete at which point it is popped off of the stack.
Now, a recursive function calls itself. That means another instance of the function will be
placed on the stack and will remain there until the function completes.

You need to look at a recursive function in terms of the program stack. Lets use factorial as
an example. 5 factorial is 5x4x3x2x1 = 120 and this can be implemented recursively.
int f(int x){
if(x = = 1)
return 1;// line 1
Else
return f(x-1)*x; // line 2
}
void main()
{
int y = f(5);// main call // y should get 120
}
QUEUES
A queue is a linear collection or linear list in which insertion can take place only at one end,
called rear of the list, and deletions can take place only at other end, called front of the list,.
The behaviour of a queue is like a First-In-First-Out (FIFO) system. In queue terminology, the
insertion and deletion operations are known as enqueue and dequeue operations.

Queue can be implemented in following two ways:-


1. Queue (Using Array)
2. Queue (Using Linked List)
Queue as an ADT

A queue in memory using structure is defined as:-

#define CAPACITY 50
typedef struct queue
{ int front, rear ;
int element[CAPACITY];
} q;

Using array:

#define SIZE 10
int queue[SIZE], rear= -1, front=-1;

Operations on Queue
The following operations can be performed on Queue:-
1. Createqueue - To create an empty queue
2. Enqueue - To add (insert) and element in the queue
3. Dequeue - To access and remove an element of the queue
4. Peek - To access the first element of the queue without removing it.
5. Isfull - To check whether the queue is full
6. Isempty - To check whether the queue is empty

Condition for isFull()

int isFull()
{
if(rear == maxsize -1)
return 1;
else
return 0;
}

Condition for IsEmpty()

int isEmptyl()
{
if((front == -1 || front > rear)
return 1;
else
return 0;
}
Algorithm for Enqueue:

Step 1: IF REAR = MAX - 1


Write OVERFLOW Go to step [END OF IF]
Step 2: IF FRONT = -1 and REAR = -1
SET FRONT = REAR = 0
ELSE
SET REAR = REAR + 1 [END OF IF]
Step 3: Set QUEUE[REAR] = NUM
Step 4: EXIT

Algorithm for Dequeue:

Step 1: IF FRONT = -1 or FRONT > REAR


Write UNDERFLOW
ELSE
SET VAL = QUEUE[FRONT]
SET FRONT = FRONT + 1 [END OF IF]
Step 2: EXIT
Applications of Queues:

1. Serving requests on a single shared resource, like a printer, CPU task scheduling etc.
2. In real life scenario, Call Centre phone systems uses Queues to hold people calling them
in an order, until a service representative is free.
3. Handling of interrupts in real-time systems. The interrupts are handled in the same order
as they arrive i.e First come first served.
There are various applications of computer science, which are performed using data
structure queue. This data structure is usually used in-
● Simulation
● Various features of operating system [Operating systems often maintain a queue of
processes that are ready to execute or that are waiting for a particular event to
occur.]
● Multi-programming platform systems
● Different type of scheduling algorithm
● Round robin technique
● Printer server routines
● Various applications software is also based on queue data structure Operating
systems often maintain a queue of processes that are ready to execute or that are
waiting for a particular event to occur.

Limitations of Linear Queue


If the last position of the queue is occupied then it is not possible to enqueue any more
elements in the queue even though some positions are vacant towards the front position of
the queue for example according to the rear position queue is full but 5 positions are still
blank in the queue
CIRCULAR QUEUE

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. It is also called ‘Ring Buffer’.

Circular queue using structure:

#define CAPACITY[50];
struct cqueue
{
int front, rear; int element[CAPACITY];
} cq;

Circular queue using array:

#define SIZE 10
int queue[SIZE], rear= -1, front=-1;

Operations on Circular Queue

The following operations can be performed on Circular Queue:-


1. Createqueue - To create an empty queue
2. Enqueue - To add (insert) and element in the queue
3. Dequeue - To access and remove an element of the queue
4. Peek - To access the first element of the queue without removing it.
5. Isfull - To check whether the queue is full
6. Isempty - To check whether the queue is empty
Algorihtm for Enqueue:
● Step 1: Check if the queue is full (Rear + 1 % Maxsize = Front)
● Step 2: If the queue is full, there will be an Overflow error
● Step 3: Check if the queue is empty, and set both Front and Rear to 0
● Step 4: If Rear = Maxsize - 1 & Front != 0 (rear pointer is at the end of the
queue and front is not at 0th index), then set Rear = 0
● Step 5: Otherwise, set Rear = (Rear + 1) % Maxsize
● Step 6: Insert the element into the queue (Queue[Rear] = x)
● Step 7: Exit

Algorithm for Dequeue:


● Step 1: Check if the queue is empty (Front = -1 & Rear = -1)
● Step 2: If the queue is empty, Underflow error
● Step 3: Set Element = Queue[Front]
● Step 4: If there is only one element in a queue, set both Front and Rear to -1
(IF Front = Rear, set Front = Rear = -1)
● Step 5: And if Front = Maxsize -1 set Front = 0
● Step 6: Otherwise, set Front = Front + 1
● Step 7: Exit

Application of Circular Queue

Below we have some common real-world examples where circular queues are used:

1. Computer controlled Traffic Signal System uses circular queue.


2. CPU scheduling and Memory management.

You might also like