0% found this document useful (0 votes)
3 views

stack

Chapter 3 discusses stacks, a linear data structure that follows the Last In, First Out (LIFO) principle, detailing memory representation using arrays, operations such as push and pop, and applications including postfix expression evaluation and infix to postfix conversion. It also covers recursion and how stacks manage function calls. The chapter includes algorithms and sample code for implementing stack operations and converting expressions.

Uploaded by

divya R K
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

stack

Chapter 3 discusses stacks, a linear data structure that follows the Last In, First Out (LIFO) principle, detailing memory representation using arrays, operations such as push and pop, and applications including postfix expression evaluation and infix to postfix conversion. It also covers recursion and how stacks manage function calls. The chapter includes algorithms and sample code for implementing stack operations and converting expressions.

Uploaded by

divya R K
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 34

DATA STRUCTURES AND APPLICATIONS

CHAPTER 3: STACK

3.1 STACK
3.1.1 MEMORY REPRESENTATION OF STACKS (USING ARRAYS)
3.2 OPERATIONS ON STACK
3.2.1 PUSH OPERATION
3.2.2 POP OPERATION
3.3 APPLICATIONS OF STACK
3.3.1 EVALUATION OF POSTFIX-EXPRESSION
3.3.2 INFIX TO POSTFIX CONVERSION
3.3.3 RECURSION

STACK
3-1
DATA STRUCTURES AND APPLICATIONS

CHAPTER 3: STACK

3.1 STACK
Definition
• A stack is a linear data-structure.
• It follows the Last In, First Out (LIFO) principle.
Key Features
• Elements are added or removed only from one end called the top.
Operations
1) Insert: An element is inserted from top end. Insertion operation is called
push operation.
2) Delete: An element is deleted from top end. Deletion operation is called pop
operation.
3) Overflow: Check whether the stack is full or not.
4) Underflow: Check whether the stack is empty or not.
Applications
1) Converting infix expressions to postfix.
2) Evaluating postfix-expressions.
3) Managing function calls during recursion.

Figure 3.1: Stack

3.1.1 MEMORY REPRESENTATION OF STACKS (USING ARRAYS)


• A stack can be implemented using arrays where:
i) An array stores the stack elements, i.e., stack[size].
ii) A variable top indicates the index of the topmost element in the stack.
• Key Conditions:
When top = -1, the stack is empty.
When top = size - 1, the stack is full.

3.2 OPERATIONS ON STACK


3.2.1 PUSH OPERATION
Definition
• Adds an element to the top of the stack.
STACK
3-2
DATA STRUCTURES AND APPLICATIONS

Figure 3.2: Push Operation


Algorithm
1) Check for Overflow: Verify if the stack is full (i.e., top == size - 1).
2) Increment the Top: If space is available, increase top by 1.
3) Insert the Element: Place the new element at stack[top].
Function to add an element to the stack
void push()
{
if (top == (SIZE - 1))
{
cout << "Stack Overflow" << endl;
}
else
{
top = top + 1;
cout << "Enter the element to be pushed: "; cin >> stack[top];
}

STACK
3-3
DATA STRUCTURES AND APPLICATIONS

3.2.2 POP OPERATION


Definition
• Removes the top element of the stack.

Figure 3.3: Pop Operation


Algorithm
1) Check for Underflow: Verify if the stack is empty (top == -1).
2) Remove the Top Element: If elements are present, remove the value at
stack[top].
3) Decrement the Top: Decrease top by 1.
Function to delete an element from the stack
void pop()
{
if (top == -1)
{
cout << "Stack Empty" << endl;
}
else
{
cout << "Popped element is = " << stack[top]<< endl; top = top - 1;
}
}

STACK
3-4
DATA STRUCTURES AND APPLICATIONS

Program to implement a stack using array


#include <iostream>
#define SIZE 5
int stack[SIZE], top;

void push() // Function to add an element to the stack


{
if (top == (SIZE - 1))
{
cout << "Stack Overflow" << endl;
}
else
{
top = top + 1;
cout << "Enter the element to be pushed: ";
cin >> stack[top];
}
}

void pop() // Function to delete an element from the stack


{
if (top == -1)
{
cout << "Stack Empty" << endl;
}
else
{
cout << "Popped element is = " << stack[top]<< endl;
top = top - 1;

STACK
3-5
DATA STRUCTURES AND APPLICATIONS

}
}

void display() // Function to display the status of the stack


{
if (top == -1)
{
cout << "Stack Empty" << endl;
}
else
{
cout << "\nItems in Stack:" << endl;
for (int i = top; i >= 0; i--)
{
cout << stack[i] << endl;
}
}
}
int main()
{
int choice; top
= -1;

while (true)
{
cout << "1. PUSH" << endl; cout
<< "2. POP" << endl; cout << "3.
DISPLAY" << endl; cout << "4.
EXIT" << endl; cout << "Enter
your choice: "; cin >> choice;

switch (choice)
{
case 1:
push();
break;
case 2:
pop();
break;
case 3:
display();
break;
case 4:
return 0; default:
cout << "Invalid choice! Please try again." << endl;
}
}

STACK
3-6
DATA STRUCTURES AND APPLICATIONS

return 0;
}

3.3 APPLICATIONS OF STACK


3.3.1 EVALUATION OF POSTFIX-EXPRESSION
• The stack is used to evaluate postfix-expressions.
• Operands are pushed, and operators are applied to operands popped from the
stack.
Algorithm for Evaluation of Postfix-expression
1) Initialize an empty stack to store operands.
2) Scan the postfix-expression from left to right, token by token.
3) For each token, perform the following steps:
o If the token is an operand:
 Push the operand onto the stack.
o If the token is an operator:
 Pop the top two elements from the stack.
Let the first popped element be operand2 & the second be operand1
 Apply the operator to operand1 and operand2 (e.g., operand1
operator operand2).
 Push the result of the operation back onto the stack.
4) After scanning the expression:
o The final result will be the only element remaining in the stack.
Pop and return it as the result

Example 1: Postfix-expression 3 4 X 2 +

Example 2: Postfix-expression 7 8 2 * 4 /+

STACK
3-7
DATA STRUCTURES AND APPLICATIONS

Example 3: Postfix-expression 2 3 4 X +

STACK
3-8
DATA STRUCTURES AND APPLICATIONS

Example 4: Postfix-expression 3 4 X 2 5 X +

STACK
3-9
DATA STRUCTURES AND APPLICATIONS

Program to evaluate the given postfix-expression


#include <iostream>
#include <cctype>
#include <cstring>
using namespace std;

int top = -1;


float s[20], value[20];
char postfix[40];

float eval();
void push(float num);
float pop();

int main() {
int i;
float result;

cout << "Enter the postfix-expression:" << endl;


cin >> postfix;

i = 0;
while (postfix[i] != '\0') {
if (isalpha(postfix[i])) {
cout << "Enter value for operand " << postfix[i] << ": ";
cin >> value[i];
}
i++;
}

result = eval();
cout << "Result = " << result << endl;

return 0;
}

float eval() {
int i = 0;
float op1, op2, res;

while (postfix[i] != '\0') {


if (isalpha(postfix[i])) {
push(value[i]);
} else {
op2 = pop();
op1 = pop();

STACK
3-10
DATA STRUCTURES AND APPLICATIONS

switch (postfix[i]) {
case '*':
push(op1 * op2);
break;
case '/':
push(op1 / op2);
break;
case '+':
push(op1 + op2);
break;
case '-':
push(op1 - op2);
break;
default:
break;
}
}
i++;
}
res = pop();
return res;
}

void push(float num) {


top = top + 1;
s[top] = num;
}

float pop() {
float num = s[top];
top = top - 1;
return num;
}
Output:
Enter the postfix-expression:
ab+
Enter value for operand a: 5
Enter value for operand b: 3
Result = 8

STACK
3-11
DATA STRUCTURES AND APPLICATIONS

3.3.2 INFIX TO POSTFIX CONVERSION


• The stack is used to temporarily store operators during the conversion of an infix
expression (e.g., A + B) to postfix form (e.g., AB+).
Algorithm for Conversion of Infix to Postfix Using Stack
1) Initialize an empty stack S and an empty postfix-expression P.
2) Scan the infix expression from left to right.
3) For each token in the infix expression, perform the following steps:
o If the token is an operand:
 Append it directly to the postfix-expression P.
o If the token is an opening parenthesis (:
 Push it onto the stack S.
o If the token is a closing parenthesis ):
 Pop from the stack S and append each popped operator to P until
an opening parenthesis ‘(‘ is encountered.
 Discard the opening parenthesis ‘(‘ from the stack.
o If the token is an operator (e.g., +, -, *, /, ^):
 While the stack is not empty and the precedence of the operator at
the top of the stack is greater than or equal to the precedence of
the current operator:
 Pop from the stack S and append the operator to P.
 Push the current operator onto the stack.
4) After scanning the infix expression:
o Pop any remaining operators from the stack S and append them to P.
5) The final postfix-expression is stored in P.

STACK
3-12
DATA STRUCTURES AND APPLICATIONS

Example 5: Infix expression (x + y)/(z*8)

STACK
3-13
DATA STRUCTURES AND APPLICATIONS

Example 6: Infix expression 2 X 3 + 4 X 5

Example 7: Infix expression 2 – 3 + 4 – 5 X 6

STACK
3-14
DATA STRUCTURES AND APPLICATIONS

Program to convert an infix expression to postfix


#include <iostream>
#include <cstring>

// Function to return precedence of operators for stack (F)


int F(char symbol) {
switch (symbol) {
case '+':
case '-': return 2;
case '*':
case '/': return 4;
case '^':
case '$': return 5;
case '(': return 0;
case '#': return -1;
default : return 8;
}
}

// Function to return precedence of operators for input (G)


int G(char symbol) {
switch (symbol) {
case '+':
case '-': return 1;
case '*':
case '/': return 3;
case '^':
case '$': return 6;
case '(': return 9;
case ')': return 0;
default : return 7;
}
}

// Function to convert infix to postfix


void infix_postfix(const char infix[], char postfix[]) {
int top, i, j;
char s[30], symbol;
top = -1;
s[++top] = '#'; // Initial stack
j = 0;

for (i = 0; i < strlen(infix); i++) {


symbol = infix[i];
while (F(s[top]) > G(symbol)) {
postfix[j] = s[top--];
j++;

STACK
3-15
DATA STRUCTURES AND APPLICATIONS

}
if (F(s[top]) != G(symbol)) {
s[++top] = symbol;
} else {
top--;
}
}

while (s[top] != '#') {


postfix[j++] = s[top--];
}
postfix[j] = '\0'; // Null-terminate the postfix-expression
}

// Main function
int main() {
char infix[20];
char postfix[20];

cout << "Enter a valid infix expression:\n";


cin >> infix;

infix_postfix(infix, postfix);

cout << "The postfix-expression is:\n";


cout << postfix << endl;

return 0;
}
Output:
Enter a valid infix expression:
a+b*c
The postfix-expression is:
abc*+

STACK
3-16
DATA STRUCTURES AND APPLICATIONS

3.3.3 RECURSION
• The stack is used to store function call details during recursion in programming.
• Each function call is pushed onto the stack and popped when completed.
• The stack ensures function calls are stored and retrieved in a LIFO order.
Activation Record
• Each function call creates an activation record stored in the stack.
• An activation record contains:
1) Arguments: Values passed to the function.
2) Local Variables: Variables declared inside the function.
3) Return Address: Address of the calling function or where the control will
return after the function execution.
Working of Recursion
1) A recursive function keeps calling itself until a base case is reached.
2) Each recursive call creates a new activation record pushed onto the stack.
3) The stack ensures the most recent function call is solved first, adhering to the LIFO
principle.
4) After the base case is resolved, the program backtracks by solving the previous
function calls using the stored activation records.

Figure 3.4: Recursive call to find factorial Figure 3.5: Activation Record

STACK
3-17
DATA STRUCTURES AND APPLICATIONS

CHAPTER 4: QUEUE

4.1 QUEUE
4.1.1 MEMORY REPRESENTATION OF QUEUES (USING ARRAYS)
4.2 OPERATIONS ON QUEUE
4.2.1 INSERT OPERATION
4.2.2 DELETE OPERATION
4.3 TYPES OF QUEUES (VARIATIONS OF QUEUES)
4.3.1 CIRCULAR-QUEUE
4.3.1.1 MEMORY REPRESENTATION OF CIRCULAR-QUEUES
4.3.1.2 OPERATIONS ON CIRCULAR-QUEUE
4.3.2 DEQUEUE (DOUBLE-ENDED QUEUE)
4.3.3 PRIORITY-QUEUES
4.3 APPLICATIONS OF QUEUES

QUEUE
4-1
DATA STRUCTURES AND APPLICATIONS

CHAPTER 4: QUEUE

4.1 QUEUE
Definition
• A queue is a linear data-structure.
• It follows the FIFO (First In, First Out) principle.
Key Features
• Elements are added at one end called the rear (or tail).
• Elements are removed from the other end called the front (or head).
Operations
1) Insert: An element is added at the rear-end.
2) Delete: An element is removed from the front-end.
3) Overflow: Check whether the queue is full or not.
4) Underflow: Check whether the queue is empty or not.
Applications
1) Scheduling processes in operating systems.
2) Handling requests in printers.
3) Managing calls in call centers (customer service).

Figure 4.1: Queue

4.1.1 MEMORY REPRESENTATION OF QUEUES (USING ARRAYS)


• A queue can implement using arrays where:
i) An array holds the queue elements, i.e., `queue[size]`.
ii) Two variables, front and rear, indicate the positions of the front most and
rearmost elements in the queue.
• Key Conditions
When front = -1 and rear = -1, the queue is empty.
When rear = size - 1 and front = 0, the queue is full (in a simple queue).

QUEUE
4-2
DATA STRUCTURES AND APPLICATIONS

4.2 OPERATIONS ON QUEUE


4.2.1 INSERT OPERATION
Definition
• Adds an element to the rear of the queue.

Figure 4.2: Insert Operation

Algorithm
1) Check for Overflow: Verify if the queue is full (rear == size - 1).
2) Insert the Element: If space is available:
o Increment rear by 1.
o Insert the new element at queue[rear].
Function to Add an Element to the Queue
void insert() {
if (rear == SIZE - 1) {
cout << "Queue Overflow" << endl;
} else {
rear = rear + 1;
cout << "Enter the element to be inserted: "; cin >>
queue[rear];
}
if (front == -1) { front = 0;
}
}
QUEUE
4-3
DATA STRUCTURES AND APPLICATIONS

4.2.2 DELETE OPERATION


Definition
• Removes the front element of the queue.

Figure 4.3: Delete Operation

Algorithm
1) Check for Underflow: Verify if the queue is empty (front == -1 or front > rear).
2) Remove the Element: If elements are present:
o Remove the value at queue[front].
o Increment front by 1.
3) Reset Queue (if Empty): If front == rear, reset both front and rear to -1.
Function to delete an element from the queue
void DeleteQ() {
if (front == -1) {
cout << "Queue Underflow" << endl;
} else {
cout << "The element deleted is " << queue[front] << endl; if (front == rear) {
front = -1;
rear = -1;
} else {
front = front + 1;
}
}

}
QUEUE
4-4
DATA STRUCTURES AND APPLICATIONS

Program to implement a queue using an array.


#include <iostream>
#include <cstdlib>
#define SIZE 4

using namespace std;

int rear = -1, front = -1;


int queue[10];

void insert() {
if (rear == SIZE - 1) {
cout << "Queue Overflow" << endl;
} else {
rear = rear + 1;
cout << "Enter the element to be inserted: ";
cin >> queue[rear];
}
if (front == -1) {
front = 0;
}
}

void DeleteQ() {
if (front == -1) {
cout << "Queue Underflow" << endl;
} else {
cout << "The element deleted is " << queue[front] << endl;
if (front == rear) {
front = -1;
rear = -1;
} else {
front = front + 1;
}
}
}

void display() {
if (front == -1) {
cout << "Queue is empty" << endl;
} else {
for (int i = front; i <= rear; i++) {
cout << queue[i] << endl;
}
}
}

QUEUE
4-5
DATA STRUCTURES AND APPLICATIONS

int main() { int ch = 1;

while (ch) {

cout << "1. Insert" << endl; cout << "2. Delete" << endl; cout << "3. Display" <<
endl; cout << "4. Exit" << endl; cout << "Enter your choice: "; cin >> ch;

switch (ch) { case 1:

insert(); break;

case 2:

DeleteQ(); break;

case 3:

display(); break;

case 4:

exit(0); break;

default:

cout << "Invalid choice" << endl;

return 0;

QUEUE
4-6
DATA STRUCTURES AND APPLICATIONS

4.3 TYPES OF QUEUES (VARIATIONS OF QUEUES)


4.3.1 CIRCULAR-QUEUE
Definition
• A circular-queue is a linear data-structure where the last position connects back to
the first, forming a circle.
• It follows the FIFO principle.
Key Features
• Elements are added at the rear and removed from the front.
• The queue is circular, meaning:
When rear reaches the last position, it wraps around to the first position if space
is available.
• Memory is used efficiently by reusing empty spaces.
Applications
• Buffer management in computers and real-time systems.
• Handling streaming data like audio or video.

Figure 4.4: Circular-queue

4.3.1.1 MEMORY REPRESENTATION OF CIRCULAR-QUEUES (USING ARRAYS)


• A circular-queue can implement using arrays where:
i) An array holds the queue elements, i.e., `queue[size]`.
ii) Two variables, front and rear, track the positions of the first and last
elements in the queue.
• Key Conditions
When front = -1 and rear = -1, the queue is empty.

QUEUE
4-7
DATA STRUCTURES AND APPLICATIONS

When (rear + 1) % size == front, the queue is full.

3.1.2 OPERATIONS ON CIRCULAR-QUEUE


INSERT OPERATION
Definition
• Adds an element to the rear of the circular-queue.
Algorithm
1) Check for Overflow: If (rear + 1) % size == front, the queue is full.
2) Insert the Element: If space is available:
o Increment rear as (rear + 1) % size.
o Insert the new element at queue[rear].
3) Initialize Front (if Needed): If front == -1, set front = 0.

Figure 4.5: Insert Operation Function to Add an

void insert() {
if ((rear + 1) % SIZE == front) {
cout << "Queue Overflow" << endl;
} else {
rear = (rear + 1) % SIZE;
cout << "Enter the element to be inserted: "; cin >> queue[rear];
if (front == -1) { front = 0;
}

}
}

QUEUE
4-8
DATA STRUCTURES AND APPLICATIONS

DELETE OPERATION
Definition
• Removes the front element of the circular-queue.

Figure 4.6: Delete Operation

Algorithm
1) Check for Underflow: If front == -1, the queue is empty.
2) Remove the Element: If elements are present:
o Remove the value at queue[front].
o Increment front as (front + 1) % size.
3) Reset Queue (if Empty): If front == rear, reset both front and rear to -1.
Function to Delete an Element from the Circular-queue
void DeleteQ() {
if (front == -1) {
cout << "Queue Underflow" << endl;
} else {
cout << "The element deleted is " << queue[front] << endl; if (front == rear) {
front = -1;
rear = -1;
} else {
front = (front + 1) % SIZE;
}
}

}
QUEUE
4-9
DATA STRUCTURES AND APPLICATIONS

Illustration Of Insert Operation And Delete Operation

QUEUE
4-10
DATA STRUCTURES AND APPLICATIONS

QUEUE
4-11
DATA STRUCTURES AND APPLICATIONS

Program to implement a circular-queue using an array.


#include <iostream>
#include <cstdlib>
#define SIZE 4

int rear = -1, front = -1;


int queue[10];

void insert() {
if ((rear + 1) % SIZE == front) {
cout << "Queue Overflow" << endl;
} else {
rear = (rear + 1) % SIZE;
cout << "Enter the element to be inserted: ";
cin >> queue[rear];
if (front == -1) {
front = 0;
}
}
}

void DeleteQ() {
if (front == -1) {
cout << "Queue Underflow" << endl;
} else {
cout << "The element deleted is " << queue[front] << endl;
if (front == rear) {
front = -1;
rear = -1;
} else {
front = (front + 1) % SIZE;
}
}
}
void display() {
if (front == -1) {
cout << "Queue is empty" << endl;
} else {
for (int i = front; i <= rear; i++) {
cout << queue[i] << endl;
}
}
}
int main() { int ch = 1;
while (ch) {

QUEUE
4-12
DATA STRUCTURES AND APPLICATIONS

cout << "1. Insert" << endl; cout << "2. Delete" << endl; cout << "3. Display"
<< endl; cout << "4. Exit" << endl; cout << "Enter your choice: "; cin >> ch;
switch (ch) { case 1:
insert(); break;
case 2:
DeleteQ(); break;
case 3:
display(); break;
case 4:
exit(0); break;
default:
cout << "Invalid choice" << endl;
}
}
return 0;
}

4.3.2 DEQUEUE (DOUBLE-ENDED QUEUE)


Definition
• A dequeue is a type of queue where elements can be added or removed from both
ends (front and rear).

Figure 4.7: Dequeue

Key Features
• It is not restricted to the FIFO principle.
• Supports insertion and deletion at both ends of the queue.
Types of Dequeues
1) Input-Restricted Dequeue: Insertion is allowed only at one end, but deletion
can be done from both ends.
2) Output-Restricted Dequeue: Deletion is allowed only at one end, but insertion can
be done from both ends.

QUEUE
4-13
DATA STRUCTURES AND APPLICATIONS

Figure 4.8: Input-Restricted Dequeue

Figure 4.9: Output-Restricted Dequeue

Applications
• Used in implementing sliding window algorithms.
• Helpful in managing tasks where operations at both ends are required, such as undo
functionality.

4.3.3 PRIORITY-QUEUES
Definition
• A priority-queue stores elements based on their priority instead of their arrival
order.
Key Features
• Elements with higher priority are processed before elements with lower priority.
• If two elements have the same priority, they are processed based on their order of
arrival (FIFO).
Operations
1) Insert: Add an element to the queue along with its priority.
2) Delete: Remove the element with the highest priority.
Types
1) Max-Priority-queue: Processes elements with the highest priority first.
2) Min-Priority-queue: Processes elements with the lowest priority first.
Applications
• Scheduling tasks in operating systems (e.g., job scheduling).
• Managing data in simulations and network routing.

QUEUE
4-14
DATA STRUCTURES AND APPLICATIONS

Figure 4.10: Min-Priority-queue Figure 4.11: Max-Priority-queue

4.4 APPLICATIONS OF QUEUES


Job Scheduling
• Operating systems use queues to manage tasks or processes based on their priority
or arrival time.
CPU Task Management
• Multiple processes waiting for CPU time are stored in a queue.
• The scheduler allocates CPU to these processes in a specific order, like FCFS
Printer Task Management
• When multiple print requests are made, they are stored in a queue.
• The printer processes them one by one in the order they were received.
Data Buffering
• Queues are used in buffering applications like handling input/output devices or
managing data in network communications.
Call Centers
• Customer calls waiting to be attended are placed in a queue.
• They are answered based on the order of their arrival.
Breadth-First Search (BFS)
• Queues are used in BFS algorithms in graph traversal to keep track of the next node
to visit.
Traffic Management
• Queues are used to simulate and analyze traffic systems, like cars waiting at a
traffic signal.
Messaging Systems
• Queues are used in asynchronous messaging systems, where messages are stored
temporarily until the receiver processes them.
Shared Resources
• Multi-user systems use queues to manage access to shared resources, such as
printers or databases.
Simulation Systems
• Queues are used in simulation models, such as customer queues in banks or service
centers.

QUEUE
4-15
DATA STRUCTURES AND APPLICATIONS

QUEUE
4-16
DATA STRUCTURES AND APPLICATIONS

QUEUE
4-17

You might also like