0% found this document useful (0 votes)
11 views25 pages

Chapter 1 Dsa

This document provides a comprehensive overview of stacks, a linear data structure that operates on a Last In, First Out (LIFO) principle. It covers types of stacks, basic operations, real-life applications such as infix to postfix conversion and decimal to binary conversion, as well as the advantages and disadvantages of using stacks. Key operations like push, pop, and peek are explained along with their implementations in C programming.

Uploaded by

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

Chapter 1 Dsa

This document provides a comprehensive overview of stacks, a linear data structure that operates on a Last In, First Out (LIFO) principle. It covers types of stacks, basic operations, real-life applications such as infix to postfix conversion and decimal to binary conversion, as well as the advantages and disadvantages of using stacks. Key operations like push, pop, and peek are explained along with their implementations in C programming.

Uploaded by

sahnitesh066
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 25

Chapter 1: Introduction of Stacks

Overview
A stack is a linear data structure that follows the Last In, First
Out (LIFO) principle. This means that the last item added
(pushed) to the stack is the first one to be removed (popped).
Think of a stack like a pile of plates — you can only add or
remove the top plate.

Types of Stack:
 Fixed Size Stack : As the name suggests, a fixed size
stack has a fixed size and cannot grow or shrink
dynamically. If the stack is full and an attempt is made to
add an element to it, an overflow error occurs. If the stack
is empty and an attempt is made to remove an element
from it, an underflow error occurs.
 Dynamic Size Stack : A dynamic size stack can grow or
shrink dynamically. When the stack is full, it automatically
increases its size to accommodate the new element, and
when the stack is empty, it decreases its size. This type of
stack is implemented using a linked list, as it allows for
easy resizing of the stack.

Basic Operations
1. Push: Adds an element to the top of the stack.
2. Pop: Removes the top element from the stack.
3. Peek (Top): Returns the top element without removing it.
4. isEmpty: Checks if the stack is empty.
5. isFull (in some implementations): Checks if the stack
has reached its capacity.

1
Representation of Stack Data Structure:
Stack follows LIFO (Last In First Out) Principle so the element
which is pushed last is popped first.

Representation of Stack
struct stack {
type array[MAX_SIZE];
int top;
}

2
Chapter 2 : Operations
The key operations performed on a stack are:
1. Push: Adds an element to the top of the stack.
2. Pop: Removes the top element from the stack.
3. Peek/Top: Returns the top element of the stack without
removing it.
4. isEmpty: Checks if the stack is empty.

5. isFull: Checks if the stack is full.


------------------------------------------------------------
---------------
Push Operation
Definition: Adds an element to the top of the stack if it's not
full.

Function for push operation is :

void push(Stack *s, int value) {


if (isFull(s)) {
printf("Stack Overflow! Cannot push %d.\n", value);
return;
}
s->data[++(s->top)] = value;
printf("%d pushed to stack.\n", value);
}

3
------------------------------------------------------------
---------------
Pop Operation
Definition: Removes and returns the top element of the stack
if it's not empty.
Function for pop operation is :

int pop(Stack *s) {


if (isEmpty(s)) {
printf("Stack Underflow! Cannot pop from an empty stack.\
n");
return -1; // Sentinel value indicating error
}
return s->data[(s->top)--];
}

------------------------------------------------------------
---------------
Peek Operation
Definition: Returns the top element without removing it if the
stack is not empty.

Function for peek operation is :

int peek(Stack *s) {


if (isEmpty(s)) {
printf("Stack is empty. Nothing to peek.\n");

4
return -1; // Sentinel value indicating error
}

return s->data[s->top];
}
------------------------------------------------------------
-------------
Check if Stack is Empty
Definition: Returns 1 (true) if the stack is empty, otherwise 0
(false).
Function to check if stack is empty :

int isEmpty(Stack *s) {


return s->top == -1;
}
------------------------------------------------------------
---------------

Check if Stack is Full


Definition: Returns 1 (true) if the stack is full, otherwise 0
(false).
Function to check if stack is full :

int isFull(Stack *s) {


return s->top == MAX - 1;
}

5
------------------------------------------------------------
---------------

Display Stack
Definition: Displays all elements currently in the stack.

Function to display the elements of the


stack :

void display(Stack *s) {


if (isEmpty(s)) {
printf("Stack is empty.\n");
return;
}
printf("Stack elements: ");
for (int i = 0; i <= s->top; i++) {
printf("%d ", s->data[i]);
}
printf("\n");
}
-------------------------------------------------------------------
-----------------

6
Program for the real life implementation of stack
in redo and undo function :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 5
#define ACTION_SIZE 50

// Stack structure to store actions


typedef struct {
char actions[MAX][ACTION_SIZE];
int top;
} Stack;

// Function to initialize the stack


void initialize(Stack *s) {
s->top = -1;
}

// Function to check if the stack is empty


int isEmpty(Stack *s) {

7
return s->top == -1;
}

// Function to check if the stack is full


int isFull(Stack *s) {
return s->top == MAX - 1;

// Function to push an action onto the stack


void push(Stack *s, const char *action) {
if (isFull(s)) {
printf("Stack Overflow! Cannot perform
'%s'.\n", action);
return;
}
strcpy(s->actions[++(s->top)], action);
printf("Action '%s' performed.\n", action);
}

// Function to pop an action from the stack


char* pop(Stack *s) {
if (isEmpty(s)) {

8
printf("Stack Underflow! No actions to undo.\
n");
return NULL;
}
return s->actions[(s->top)--];
}

// Function to peek at the top action of the stack


char* peek(Stack *s) {
if (isEmpty(s)) {
printf("Stack is empty.\n");
return NULL;
}
return s->actions[s->top];
}

// Function to display the stack contents


void display(Stack *s) {
if (isEmpty(s)) {
printf("Stack is empty.\n");
return;
}

9
printf("Current actions in stack: ");
for (int i = 0; i <= s->top; i++) {
printf("%s ", s->actions[i]);
}
printf("\n");
}

// Function to perform an undo operation


void undo(Stack *undoStack, Stack *redoStack) {
if (isEmpty(undoStack)) {
printf("Nothing to undo.\n");
return;
}
char *action = pop(undoStack);
if (action != NULL) {
push(redoStack, action);
printf("Undo action: '%s'\n", action);
}
}

// Function to perform a redo operation


void redo(Stack *redoStack, Stack *undoStack) {
if (isEmpty(redoStack)) {
10
printf("Nothing to redo.\n");
return;
}
char *action = pop(redoStack);
if (action != NULL) {
push(undoStack, action);
printf("Redo action: '%s'\n", action);
}
}

// Main function to demonstrate the Undo/Redo


functionality
int main() {
Stack undoStack, redoStack;
initialize(&undoStack);
initialize(&redoStack);

// Simulate actions
push(&undoStack, "Type 'Hello'");
push(&undoStack, "Type 'World'");
push(&undoStack, "Delete 'World'");
display(&undoStack);

11
// Perform Undo
undo(&undoStack, &redoStack);
display(&undoStack);

// Perform Redo
redo(&redoStack, &undoStack);
display(&undoStack);

// Perform more actions


push(&undoStack, "Type 'Stack'");
display(&undoStack);

// Undo multiple times


undo(&undoStack, &redoStack);
undo(&undoStack, &redoStack);
display(&undoStack);

// Redo multiple times


redo(&redoStack, &undoStack);
redo(&redoStack, &undoStack);
display(&undoStack);

return 0;
12
}
------------------------------------------------------------
---------------

Sample output :
Action 'Type 'Hello'' performed.
Action 'Type 'World'' performed.
Action 'Delete 'World'' performed.
Current actions in stack: Type 'Hello' Type 'World' Delete
'World'
Undo action: 'Delete 'World''
Current actions in stack: Type 'Hello' Type 'World'
Redo action: 'Delete 'World''
Current actions in stack: Type 'Hello' Type 'World' Delete
'World'
Action 'Type 'Stack'' performed.
Current actions in stack: Type 'Hello' Type 'World' Delete
'World' Type 'Stack'
Undo action: 'Type 'Stack''
Undo action: 'Delete 'World''
Current actions in stack: Type 'Hello' Type 'World'

13
Redo action: 'Delete 'World''
Redo action: 'Type 'Stack''
Current actions in stack: Type 'Hello' Type 'World' Delete
'World' Type 'Stack'
------------------------------------------------------------
---------------

Chapter 3 : Applications of
stack
Stacks are fundamental data structures with a wide
range of real-life applications, especially in situations
requiring a Last In, First Out (LIFO) approach. Two
common and significant applications of stacks involve
conversion tasks.
Here are two detailed examples:

1.Infix to Postfix Expression Conversion


Background:
 Infix Notation: Operators are written between
operands (e.g., A + B).
 Postfix Notation (Reverse Polish Notation):
Operators are written after the operands (e.g., A B
+).
Computers find it easier to evaluate postfix expressions
because they don't require the use of parentheses or
operator precedence rules. The conversion from infix to
postfix uses a stack to temporarily hold operators.
14
Examples :
 Infix Expression: (A + B) * C - D
 Postfix Expression: A B + C * D -

Program for infix to postfix


conversion :

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define MAX 100

typedef struct {
char data[MAX];
int top;
} Stack;

// Initialize the stack


void initialize(Stack *s) {
s->top = -1;

15
}

// Check if the stack is empty


int isEmpty(Stack *s) {
return s->top == -1;
}

// Push an element onto the stack


void push(Stack *s, char value) {
s->data[++(s->top)] = value;
}

// Pop an element from the stack


char pop(Stack *s) {
if (isEmpty(s)) {
return '\0';
}
return s->data[(s->top)--];
}

// Get the top element of the stack


char peek(Stack *s) {
return s->data[s->top];
}

16
// Function to return precedence of operators
int precedence(char op) {
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
return 0;
}

// Infix to Postfix conversion function


void infixToPostfix(char *infix, char *postfix) {
Stack s;
initialize(&s);
int j = 0;

for (int i = 0; infix[i] != '\0'; i++) {


char ch = infix[i];

if (isalnum(ch)) {
postfix[j++] = ch;
} else if (ch == '(') {
push(&s, ch);
} else if (ch == ')') {
while (!isEmpty(&s) && peek(&s) != '(') {
postfix[j++] = pop(&s);
}
pop(&s); // Remove '(' from the stack
17
} else {
while (!isEmpty(&s) && precedence(peek(&s))
>= precedence(ch)) {
postfix[j++] = pop(&s);
}
push(&s, ch);
}
}

while (!isEmpty(&s)) {
postfix[j++] = pop(&s);
}

postfix[j] = '\0';
}

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

printf("Enter an infix expression: ");


scanf("%s", infix);

infixToPostfix(infix, postfix);

18
printf("Postfix Expression: %s\n", postfix);

return 0;
}

Output:
Enter an infix expression: (A+B)*C-D
Postfix Expression: AB+C*D-
------------------------------------------------------------
---------------
2. Decimal to Binary Conversion
Background:
The stack can be used to convert a decimal number
to its binary equivalent. This process works by
continuously dividing the number by 2 and storing the
remainders (0 or 1) in a stack. When the division
process is complete, the binary number is obtained by
popping the remainders from the stack (since the
binary digits need to be read in reverse order).
Example:
 Decimal Number: 13
o Steps:
 13 / 2 → Quotient: 6, Remainder: 1
 6 / 2 → Quotient: 3, Remainder: 0
 3 / 2 → Quotient: 1, Remainder: 1

19
 1 / 2 → Quotient: 0, Remainder: 1
o Binary: 1101

Program for binary to decimal


conversion:

#include <stdio.h>
#include <stdlib.h>

#define MAX 100

typedef struct {
int data[MAX];
int top;
} Stack;

// Initialize the stack


void initialize(Stack *s) {
s->top = -1;
}

// Check if the stack is empty

20
int isEmpty(Stack *s) {
return s->top == -1;
}

// Push an element onto the stack


void push(Stack *s, int value) {
s->data[++(s->top)] = value;
}

// Pop an element from the stack


int pop(Stack *s) {
return s->data[(s->top)--];
}

// Function to convert decimal to binary using a stack


void decimalToBinary(int num) {
Stack s;
initialize(&s);

if (num == 0) {
printf("Binary: 0\n");
return;
}

while (num > 0) {


21
push(&s, num % 2);
num /= 2;
}

printf("Binary: ");
while (!isEmpty(&s)) {
printf("%d", pop(&s));
}
printf("\n");
}

// Main function
int main() {
int number;

printf("Enter a decimal number: ");


scanf("%d", &number);

decimalToBinary(number);

return 0;
}

Output :

22
Enter a decimal number: 13
Binary: 1101
------------------------------------------------------------
--------------

Chapter 3 : Advantages and


Disadvantages of stack
Advantages of Stack
1. Efficient LIFO Operations:
o Stacks are designed to perform Last In, First
Out (LIFO) operations efficiently.
o Insertion (push) and deletion (pop) operations
take constant time, O(1).
2. Simple Implementation:
o Stacks are easy to understand and implement,
requiring only an array or linked list and a top
pointer/index.
3. Memory Management:
o Useful for managing function calls and
recursion in programming languages (call
stack).
o Local variables and function states are stored
and retrieved using the stack, making memory
management more efficient.
4. Reversing Data:

23
o Stacks are useful for reversing strings,
numbers, or other data since the last item
pushed is the first one popped.
5. Supports Undo/Redo Operations:
o Used in applications like text editors and
drawing applications to implement Undo/Redo
functionality.
6. Expression Evaluation and Parsing:
o Fundamental for evaluating or converting
mathematical expressions like infix to postfix
or evaluating postfix expressions.
7. Backtracking Algorithms:
o Useful in problems like maze solving, depth-
first search (DFS), and other backtracking
algorithms where returning to previous states
is necessary.
------------------------------------------------------------
---------------

Disadvantages of Stack
1. Limited Access:
o You can only access the top element of the
stack. Elements in the middle or bottom
cannot be accessed directly without popping
elements above them.
2. Fixed Size (in Array Implementation):
o If implemented using an array, the size of the
stack is fixed. This can lead to:

24
 Stack Overflow if the stack exceeds its
capacity.
 Wasted memory if the allocated size is too
large for the actual usage.
3. No Random Access:
o Unlike arrays or linked lists, stacks do not
allow random access to elements, which
makes certain operations inefficient.
4. Limited Flexibility:
o Stacks are suitable for specific tasks but not
ideal for general-purpose storage or
operations that require frequent access or
modifications to elements in the middle.
5. Risk of Overflow and Underflow:
o Stack Overflow occurs when pushing onto a
full stack.
o Stack Underflow occurs when popping from an
empty stack, potentially causing errors if not
handled properly.
6. Performance Issues in Some Scenarios:
o In cases where you need frequent insertion
and deletion from both ends, a deque (double-
ended queue) would be more efficient than a
stack.
------------------------------------------------------------
---------------

25

You might also like