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

DS Unit1 Stacks

The document provides a comprehensive overview of stacks, including their need, operations, and implementations using arrays and linked lists. It discusses the time and space complexities of stack operations, applications in evaluating postfix and prefix expressions, and methods for converting infix expressions to postfix. Additionally, it covers the concept of multiple stacks and recursion, detailing the types and examples of recursive functions.

Uploaded by

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

DS Unit1 Stacks

The document provides a comprehensive overview of stacks, including their need, operations, and implementations using arrays and linked lists. It discusses the time and space complexities of stack operations, applications in evaluating postfix and prefix expressions, and methods for converting infix expressions to postfix. Additionally, it covers the concept of multiple stacks and recursion, detailing the types and examples of recursive functions.

Uploaded by

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

Stacks

STACK
S
Need of Stack
Operations on stack
Implementation of Stack
Stack VS Array
Push stack algo
Stack POP
Stack POP algo
Stack peek and traverse

Push O(1), Pop O(1),Peek O(1) and Traverse


O(n)
int peek() {
#include <iostream>
if (top == -1) {
using namespace std;
cout<<"Stack is empty!\n";
return -1;
// Stack and its top element
}
int stack[10];
return stack[top];
int top = -1;
}
// Function to push an element to the stack
// Function to display the stack
void push(int value) {
void display() {
if (top == 9) {
if (top == -1) {
cout<<"Stack Overflow!\n";
cout<<"Stack is empty!\n";
return;
return;
}
}
top=top+1;
for (int i = top; i >= 0; i--)
stack[top] = value;
cout<< stack[i]<<"\n";
}
}
int main() {
// Function to pop an element from the stack
push(10);
int pop() {
push(20);
if (top == -1) {
push(30);
cout<<"Stack Underflow!\n";
cout<<"Top element: is "<< peek()<<"\n";
return -1;
display();
}
cout<<"Popped element"<< pop();
top=top-1;
Stack implementation using Linked List

Start as a Top of Stack

Push- Insertion at the beginning of the linked list

Pop- Deletion at the beginning of the linked list

peek- Print the value of the first node

Overflow: when no free space

Underflow: when start is null


Stack using linked list

Stack using an array - drawback


If we implement the stack using an array, we need to specify the array size at the
beginning(at compile time).
We can't change the size of an array at runtime. So, it will only work for a fixed number
of elements.

Solution
We can implement the stack using the linked list.
In the linked list, we can change its size at runtime.

In the stack Implementation, a stack contains a top pointer. which is the “head” of the
stack where pushing and popping items happens at the head of the list.
Understanding Stack Implementation Using Singly Linked List
When implementing a stack using singly linked list, it is essential to consider the standard operations of push, pop,
and peek. The push operation involves adding an element to the top of the stack, while the pop operation removes
the top element from the stack. The peek operation returns the value of the top element without removing it.

Suppose we insert elements 4, 3, 2, and 1 into the stack using the push operation. In push operation elements are
added to the top of the stack. In other words, the last element to be pushed onto the stack becomes the top
element, while the first element to be pushed becomes the bottom element. So, when elements are pushed onto
the stack in that order, the top of the stack will contain element 1, and the bottom of the stack will contain element
4.

When we want to access the elements in the stack, we can only access them in a LIFO (Last-In-First-Out) manner,
meaning that we can only access the top element first, followed by the second-to-top element, and so on. In other
words, we must first remove the top element using the pop operation to access the next element in the stack.

So, to access the elements in the order 1, 2, 3, and 4, we would need to pop the elements from the stack in reverse
order, starting with 1, then 2, then 3, and finally 4. This is because the top of the stack currently contains element 1,
so it must be popped first to access the next element, which is 2. The below image shows how these elements are
represented in a singly linked list.
Stack as a linked list
#include <bits stdc++.h="">
// Using this function we will be checking
using namespace std;
whether the stack is empty or not
struct Node
int isEmpty()
{
{
int data;
return top == NULL;
struct Node* link;
}
};
// Using this function we will return the top
struct Node* top;
element of the stack
// Using this function we will be pushing
int peek()
elements into the stack
{
void push(int data)
if (!isEmpty())
{
return top->data;
struct Node* tem;
else
tem = new Node();
exit(1);
if (!tem)
}
{
cout << "\nHeap Overflow";
exit(1);
}
tem->data = data;
tem->link = top;
top = tem;
}
// Using this function we will pop the top else
element of the stack {
void pop() tem = top;
{ while (tem != NULL)
struct Node* tem; {
if (top == NULL) cout << tem->data << "-> ";
{ tem = tem->link; }}}
cout << "\nStack Underflow" << endl;
exit(1); int main()
} {
else push(4);
{ push(3);
tem = top; push(2);
top = top->link; push(1);
tem->link = NULL; display();
free(tem); }} cout << "\nTop element is "<< peek() <<
endl;
void display() pop();
{ pop();
struct Node* tem; cout<<"Stack after popping 2 times \n";
if (top == NULL) display();
{ cout << "\nTop element is "<< peek() <<
cout << "\nStack Underflow"; endl;
exit(1); return 0;
} }
Complexity Analysis of Stack Implementation
Using Singly Linked List
Let’s analyze the time and space complexity of each operation in the implementation of a stack using
linked list.
1.push() Operation:
Since we always add a new element at the top of the stack, this operation takes constant time. We only
need to allocate memory for the new node, set its data, and update the "next" pointer to the current
top of the stack.
Time complexity: O(1)
Space complexity: O(1)
We only allocate memory for the new node, so the space complexity of the push operation is constant.
2.pop() Operation:
Since we always remove the top element of the stack, this operation takes constant time. We only need
to update the "top" pointer to the next node and free the memory of the removed node.
Time complexity: O(1)
Space complexity: O(1)
We only remove a node from the stack, so the space complexity of the pop operation is constant.
3. peek() Operation:
This operation only returns the value of the top element, so it takes constant time.
Time complexity: O(1)
Space complexity: O(1)
We don’t need to allocate or remove any memory, so the space complexity of the peek operation is
constant.
Applications
Postfix notation (also known as Reverse Polish Notation) is a way to represent an expression, where operators follow
their corresponding operands.

Evaluating an expression represented as postfix notation can easily be done using the stack data structure.
Stack data structure is used to efficiently evaluate Postfix Expression.
Arithmetic Expression
Infix notation : <operands><operator><operands>

Postfix notation (Reverse Polish notation): <operands> <operands> <operator>

Prefix notation (Polish notation): <operator><operands><operands>


As discussed in Infix To Postfix Conversion Using Stack, the compiler finds it convenient to evaluate an
expression in its postfix form.

The virtues of postfix form include elimination of parentheses which signify priority of evaluation and
the elimination of the need to observe rules of hierarchy, precedence and associativity during
evaluation of the expression.

What is a Postfix Expression?

As Postfix expression is without parenthesis and can be evaluated as two operands and an operator at a
time, this becomes easier for the compiler and the computer to handle.
Evaluation of Arithmetic Expression
Evaluation of Postfix Expression

Algorithm for Evaluation of Postfix Expression


1.Add ) to postfix expression.
2.Read postfix expression Left to Right until ) encountered
3.If operand is encountered, push it onto Stack
[End If]
4.If operator is encountered, Pop two elements
1.A -> Top element
2.B-> Next to Top element
3.Evaluate B operator A
4.Push B operator A onto Stack
5.Set result = pop
6.END
Evaluation of Postfix Expression
Evaluate the following Postfix Expression
623+-382/+*2&3+
Evaluation of Prefix Expression
Step 1: Start from the last element of the expression.

Step 2: check the current element.

Step2.1:
if it is an operand, push it to the stack.

Step 2.2: If it is an operator, pop two operands from the stack. A is top
element and B is next to top element. Perform the operation (A op B) and
push the result back to the stack.

Step 3: Do this till all the elements of the expression are traversed and
return the top of stack which will be the result of the operation.
Evaluation of Prefix Expression
Infix to Postfix Conversion

Method 1:
Conversion from infix to postfix expression
• Initially we have a infix expression given to us to convert to postfix notation. The infix notation is parsed from left
to right, and then converted to postfix. Assume initially the postfix expression is empty, and we will fill the postfix
expression out with the following steps:

1. If we have an opening parenthesis "(", we push it into the stack.


2. If we have an operand, we append it to our postfix expression.
3. If we have a closing parenthesis ")" we keep popping out elements from the top of the stack and
append them to our postfix expression until we encounter an opening parenthesis “(“. We pop out
the left parenthesis without appending it.

4. If we encounter an operator:-
• 4.1. If the operator has higher precedence than the one on top of the stack (We can compare ), we
push it in the stack.
• 4.2. If the operator has lower or equal precedence than the one on top of the stack, we keep
popping out and appending it to the postfix expression.
• When the last token of infix expression has been scanned, we pop the remaining elements from
stack and append them to our postfix expression.*
Algo for Infix to Postfix Conversion
using Stack
Infix to Postfix
Q.Convert infix expression to postfix

Infix expression = (A+(C+D*F+T*A)*B/C)


(A+(C+D*F+T*A)*B/C)
Multiple Stacks

A single stack is sometimes not sufficient to store a large amount of


data. To overcome this problem, we can use multiple stack. For this, we
have used a single array having more than one stack. The array is
divided for multiple stacks.

Suppose there is an array STACK[n] divided into two stack STACK


and STACK B, where n = 10.
•STACK A expands from the left to the right, i.e., from 0th element.
•STACK B expands from the right to the left, i.e., from 10th element.
•The combined size of both STACK A and STACK B never exceeds 10.
Recursion

A recursive function is defined as a function that calls itself to solve a smaller version
of its task until a final call is made which does not require a call to itself. Since a
recursive function repeatedly calls itself, it makes use of the system stack to
temporarily store the return address and local variables of the calling function. Every
recursive solution has two major cases. They are

1.Base case, in which the problem is simple enough to be solved directly without
making any further calls to the same function.

2.Recursive case, in which first the problem at hand is divided into simpler sub-parts.
Second the function calls itself but with sub-parts of the problem obtained in the first
step. Third, the result is obtained by combining the solutions of simpler sub-parts.

Every recursive function must have at least one base case. Otherwise, the recursive
function will generate an infinite sequence of calls, thereby resulting in an error
condition known as an infinite stack.
Sum of natural number
using recursion
Types of Recursion
• Direct vs Indirect recursive function :
A function is said to be directly recursive if it explicitly calls itself.
A function is said to be indirectly recursive if it contains a call to another
function which ultimately calls it.

• Linear Vs Tree recursive function :If a recursive


function calling itself for one time then it's known as Linear
Recursion. Otherwise if a recursive function calling itself for more
than one time then it's known as Tree Recursion. For example :
Linear : factorial Tree: fibnoacci
END

You might also like