0% found this document useful (0 votes)
8 views10 pages

Understanding Stack Data Structure

Uploaded by

anujbhagat031
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)
8 views10 pages

Understanding Stack Data Structure

Uploaded by

anujbhagat031
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

[Link] is Stack Data Structure?

Stack is an abstract data type with a bounded(predefined) capacity. It is a


simple data structure that allows adding and removing elements in a
particular order. Every time an element is added, it goes on the top of the
stack and the only element that can be removed is the element that is at the
top of the stack, just like a pile of objects.

1.1Basic features of Stack

1. Stack is an ordered list of similar data type.


2. Stack is a LIFO(Last in First out) structure or we can say FILO(First in
Last out).
3. push() function is used to insert new elements into the Stack
and pop() function is used to remove an element from the stack. Both
insertion and removal are allowed at only one end of Stack called Top.
4. Peek or Top: Returns top element of stack.
5. Stack is said to be in Overflow state when it is completely full and is said
to be in Underflow state if it is completely empty.

Position of Top Status of Stack

-1 Stack is Empty

0 Only one element in Stack

N-1 Stack is Full

N Overflow state of Stack


1.1.1 Push Operation
The push operation is used to insert an element into the stack. The new
element is added at the topmost position of the stack. However, before
inserting the value, we must first check if TOP=MAX–1,
because if that is the case, then the stack is full and no more insertions can
be done. If an attempt is made to insert a value in a stack that is already
full, an OVERFLOW message is printed.

Consider the stack

To insert an element with value 6, we first check if TOP=MAX–1. If the


condition is false, then we increment the value of TOP and store the new
element at the position given by stack[TOP].

1.1.2 Pop Operation


The pop operation is used to delete the topmost element from the stack.
However, before deleting the value, we must first check if TOP=-1 because if
that is the case, then it means the stack is empty and no more deletions can
be done. If an attempt is made to delete a value from a stack that is already
empty, an UNDERFLOW message is printed.

Consider the stack


To delete the topmost element, we first check if TOP=-1. If the condition is
false, then we decrement the value pointed by TOP.

1.1.3 Peek Operation


Peek is an operation that returns the value of the topmost element of the
stack without deleting it from the stack.

Here, the Peek operation will return 5, as it is the value of the topmost
element of the stack

1.1.4 isEmpty Operation : Check if stack is empty or not. If empty then


return 1 else return zero
If(top==-1)
Return 1;
Else
Return 0;
1.1.5 isfull Operation : Check if stack is full or not. If full then return 1
else return zero
If(top==n-1)
Return 1;
Else
Return 0;

1.1.6 Count Operation: count the number of element of the stack. (the
number element equivalent to top+1 )

1.2Applications of Stack
The simplest application of a stack is to reverse a word. You push a given
word to stack - letter by letter - and then pop letters from the stack.
There are other uses also like:
1. Parsing(A parser is a compiler / interpreter component that breaks data
into smaller elements for easy translation into another language. )
2. Expression Conversion(Infix to Postfix, Postfix to Prefix etc)
3. A parentheses balancing program.
4. Tracking of local variables at run time.
5. Compiler Syntax Analyzer.
6. Redo-undo features at many places like editors, photoshop.
7. Forward and backward feature in web browsers
8. Used in recursion, backtracking, graph algorithm .

1.4 Analysis of Stack Operations


Below mentioned are the time complexities for various operations that can
be performed on the Stack data structure.

 Push Operation : O(1)


 Pop Operation : O(1)
 Top Operation : O(1)
 Search Operation : O(n)
 Display operation: O(n)

The time complexities for push() and pop() functions are O(1) because we
always have to insert or remove the data from the top of the stack, which is
a one step process.

1.5 Advantages of prefix and postfix over infix notation

Both pre- and postfix have basically the same advantages over infix
notation. The most important of these are:

• much easier to translate to a format that is suitable for direct


execution. Either format can trivially be turned into a tree for further
processing, and postfix can be directly translated to code if you use a stack-
based processor or virtual machine

• entirely unambiguous. Infix notation requires precedence and


associatively rules to disambiguate it, or addition of extra parentheses that
are not usually considered part of the notation. As long as the number of
arguments to each operator are known in advance, both prefix and postfix
notation are entirely unambiguous: "* + 5 6 3" is (5+6)*3, and cannot be
interpreted as 5+(6*3), whereas parenthesis is required to achieve with
infix.
Algorithm of Infix to postfix conversation

Step1. Add unique symbol# into the stack and at end of array
infix.
Step2. Scan the symbol of array(infix expression) one by one
from left to right
Step3. If the symbol is left parenthesis ‘(‘ then add it into the
stack without checking any condition.
Step4. If the symbol is operand then add it into the output postfix
expression
Step5.
a)If symbol is operator then pop the operator which has same
precedence or higher precedence than the operator which
occurs. (ISP>=ICP)
b) add all pop operator to postfix expression .
Step6. Add scan symbol operator into stack.
Step7. i) If symbol is right parenthesis ‘)’ then pop the entire operator
from the stack until left parenthesis in stack.
ii) Remove the left parenthesis
Step8. If the pop symbol is # then pop all symbols from stack and
add them to the postfix expression except #symbol.
Step9. Do the same process until # comes in scanning array (infix
expression).

Post Fix Evaluation (Post fix to infix)


Step1. Add the unique symbol # at the end of array postfix
Step2. Scan the symbol of postfix one by one from left to right
Step3. If the symbol is operand then push in to the stack
Step4. If the symbol is operator then pop last two element of
stack, and evaluate as stack[top-1] operator stack [top] and
push into the stack
Step5. Do the same process until # comes in the in the scanning
Step6. Pop the element of stack which will be value of postfix
arithmetic expression
Pre Fix Evaluation (Pre fix to infix)
Step1. Reverse the string of prefix expression .
Step2. Add the unique symbol # at the end of array prefix
Step3. Scan the symbol of prefix one by one from left to right
Step4. If the symbol is operand then push in to the stack
Step5. If the symbol is operator then pop last two element of
stack, and evaluate as stack[top] operator stack [top-1] and
push into the stack
Step6. Do the same process until # comes in the in the scanning
Step7. Pop the element of stack which will be value of prefix
arithmetic expression

Algorithm of Infix to Prefix


Step1. Reverse the infix expression .
Step2. Add the unique symbol # into the stack and at the end of
reverse expression.
Step3. Scan the symbol of reverse infix expression one by one left to
right.
Step4. If the symbol is right parenthesis ‘)‘ then add it into the stack
without checking any condition.
Step5. If the symbol is operand then add it into the output expression .
Step6. a)If symbol is operator then pop the operator which has higher
precedence than the operator which occurs. (ISP>ICP)
b) add all pop operator to output expression.
Step7. Add scan symbol operator into stack.
Step8. i) If symbol is left parenthesis ‘(’ then pop the entire operator
from the stack until left parenthesis in stack.
ii) Remove the left parenthesis
Step9. If the pop symbol is # then pop all symbols from stack and add
them to the postfix expression except #symbol.
Step10. Do the same process until # comes in scanning array (infix
expression).
Step11. Calculate the reverse of output expression..

Algorithm of valid expression checking


Step1. Scan the symbols of expression from left to right
Step2. If the symbol is left parenthesis the push in to the stack
Step3. If the symbol is right parenthesis
step3.1: if the stack is empty then valid= False
step 3.2: else
step 3.2.1 pop the element from stack
step 3.2.2 if popped parenthesis does not match the
parenthesis being scanned valid=false
Step4. After scanning all the symbol if stack is not empty then
make valid= false

Infix to post fix :A*(B+C^D)-E^F*(G/H)

#
A A
* #* A
( #*( A
B #*( AB
+ #*(+ AB
C #*(+ ABC
^ #*(+^ ABC
D #*(+^ ABCD
) #* ABCD^+
- #- ABCD^+*
E #- ABCD^+*E
^ #-^ ABCD^+*E
F #-^ ABCD^+*EF
* #-* ABCD^+*EF^
( #-*( ABCD^+*EF^
G ABCD^+*EF^G
/ #-*(/ ABCD^+*EF^G
H #-*(/ ABCD^+*EF^GH
) #-* ABCD^+*EF^GH/*-

Infix to prefix

A*(B+C^D)-E^F*(G/H) =

)H/G(*F^E-)D^C+B(*A

(H/G)*F^E-(D^C+B)*A
Char Stack prefix
( (
H ( H
/ (/ H
G (/ HG
) HG/
* * HG/
F * HG/F
^ *^ HG/F
E *^ HG/FE
- - HG/FE^*
( -( HG/FE^*
D -( HG/FE^*D
^ -(^ HG/FE^*D
C -(^ HG/FE^*DC
+ -(+ HG/FE^*DC^
B -(+ HG/FE^*DC^B
) - HG/FE^*DC^B+
* -* HG/FE^*DC^B+
A -* HG/FE^*DC^B+A
HG/FE^*DC^B+A*-
-*A+B^CD*^EF/GH

Postfix evaluation

4,5,4,2,^,+, *,2,2,^,9,3, /, *,-

CHAR STACK
4 4
5 4,5
4 4,5,4
2 4,5,4,2
^ 4,5,16
+ 4,21
* 84
2 84,2
2 84,2,2
^ 84,4
9 84,4,9
3 84,4,9,3
/ 84,4,3
* 84,12
- 72
Prefix evaluation
+, -, 2, 7, *, 8, /, 8, 4

4,8,/,8,*,7,2,-,+

Char stack
4 4
8 4,8
/ 2
8 2,8
* 16
7 16,7
2 16,7,2
- 16,-5
+ 11

Postfix to infix
ABCD^+*EF^GH/*-

Char Stack
A A,
B A,B
C A,B,C
D A,B,C,D
^ A,B,(C^D)
+ A,(B+(C^D))
* (A*(B+(C^D)))
E (A*(B+(C^D))),E
F (A*(B+(C^D))),E,F
^ (A*(B+(C^D))), (E^F)
G (A*(B+(C^D))), (E^F),G
H (A*(B+(C^D))), (E^F),G,H
/ (A*(B+(C^D))), (E^F),(G/H)
* (A*(B+(C^D))), ((E^F)*(G/H))
- (A*(B+(C^D)))-((E^F)*(G/H))

Prefix to infix

-*A+B^CD*^EF/GH

HG/FE^*DC^B+A*-
Char Stack
H H,
G H,G
/ (G/H)
F (G/H),F
E (G/H),F,E
^ (G/H),(E^F)
* (E^F)* (G/H)
D (E^F)* (G/H), D
C (E^F)* (G/H),D,C
^ (E^F)* (G/H),(C^D)
B (E^F)* (G/H),(C^D),B
+ (E^F)* (G/H),(B+(C^D))
A (E^F)* (G/H),(B+(C^D)),A
* (E^F)* (G/H),(A*(B+(C^D)))
- (A*(B+(C^D)))-( (E^F)* (G/H))

POSTFIX TO PREFIX

ABCD^+*EF^GH/*-

CHAR STACK
A A
B A,B
C A,B,C
D A,B,C,D
^ A,B, ^CD
+ A,+B^CD
* *A+B^CD
E *A+B^CD,E
F *A+B^CD,E,F
^ *A+B^CD,^EF
G *A+B^CD,^EF,G
H *A+B^CD,^EF,G,H
/ *A+B^CD,^EF,/GH
* *A+B^CD,*^EF/GH
- -*A+B^CD*^EF/GH

Common questions

Powered by AI

A stack is distinguished by its LIFO (Last In First Out) property, meaning that the last element added is the first to be removed. This unique characteristic impacts its applications by making stacks ideal for scenarios where you need to backtrack or reverse elements, such as undo functions in software applications, expression evaluations in compilers, and maintaining the state of local variables during recursive function calls . Stacks are also fundamental for parsing and evaluating expressions from infix to postfix notation, which is crucial in compiler design and expression evaluation .

One potential drawback of using stack-based parsing is its lack of inherent contextual awareness beyond simple precedence rules, which can complicate parsing of languages requiring more complex grammatical rules. Stack-based parsing, which primarily handles arithmetic and logical expressions efficiently, might struggle with error detection or syntax validation in complex languages where context-sensitive grammar is involved. Alternative parsing methods, like recursive descent parsing, provide richer context handling and can be more intuitive when grammar rules are intricate or require backtracking .

Overflow occurs when a push operation is attempted on a full stack, leading to potential memory issues, while underflow happens when a pop operation is attempted on an empty stack, causing access errors. These conditions highlight the limitations of fixed-capacity stack implementations. Efficient stack management involves handling these conditions through checks before operations—ensuring that the stack has adequate space for pushes and non-emptiness for pops . Mitigating these conditions with dynamic resizing or alternative data structures like linked lists can improve efficiency but also introduces complexity .

When implementing stack-based infix to postfix conversion algorithms, key considerations include handling different operator precedences, associativity, and the need to process parentheses accurately. Limitations often arise from these constraints when expressions contain errors or unsupported syntax. Additionally, memory usage must be carefully managed, particularly for lengthy expressions or in constrained environments such as embedded systems. The algorithms should also be robust against malformed input, possibly through pre-parsing validations to ensure efficient processing . Enhancements might involve optimizing stack operations for specific use cases or integrating with broader parsing frameworks.

The algorithm for converting infix to postfix expression follows a structured flow, utilizing a stack to manage operators based on precedence and a resulting queue for operands. It handles parentheses by ensuring they directly influence the pull from the stack, maintaining correct mathematical ordering . While the algorithm effectively translates expressions with correct precedence handling, improvements could focus on optimizing memory usage and better error handling for malformed input expressions. Additionally, incorporating real-time syntax checking might enhance usability, ensuring that the process only proceeds with valid operations and symbols .

Postfix and prefix expressions eliminate the need for precedence rules or parentheses, making computations straightforward and less error-prone. These notations are unambiguous and are therefore more computationally efficient, as they align closely with the naturally stack-based architectures of many computing environments. Postfix, especially, aligns well with stack-based virtual machines, enabling direct execution without additional parsing steps. This characteristic reduces complexity in expression evaluation algorithms, leading to increased accuracy and reduced processing time .

Converting infix expressions to postfix expression makes evaluation easier as there are no operator precedence rules or parentheses to consider, which simplifies the computation process. The postfix format, also known as Reverse Polish Notation (RPN), is more straightforward for computers to evaluate because operators follow their operands, allowing for immediate execution using a stack. This avoids the need for backtracking and the complexities associated with operator precedence and parenthesis balancing found in infix expressions. The postfix notation is entirely unambiguous, eliminating errors related to operator precedence .

The time complexities of push and pop operations on a stack are O(1) because these operations involve manipulating only the top of the stack, making them constant time as no iteration through the elements is needed. The top operation also has O(1) complexity for similar reasons—all actions are related only to the top element. Conversely, searching or displaying elements in a stack has a time complexity of O(n) because they may require checking each element in the stack in the worst case . These complexities make stacks efficient for use cases where element access is primarily at the top of the stack.

Stack data structures facilitate backtracking by storing each state on the stack as paths in the algorithm are explored. Upon reaching a dead end, the most recent state is popped, and alternate paths are pursued, allowing for systematic exploration of all possibilities without retracing already explored paths unnecessarily. This makes stacks ideal for solving problems like mazes, constraint satisfaction puzzles, and game state searches, where it is necessary to revert to previous states and explore other options systematically . Their efficient handling of states ensures that backtracking searches are memory efficient and logical in progression.

Stack operations support the 'undo' feature by allowing the tracking of previous states; each change state is pushed onto a stack, and 'undoing' involves popping the most recent state. This LIFO behavior makes reversing changes simple and efficient . In algorithm design, particularly recursion, stacks implicitly manage function calls and local variables by storing the necessary data for each active function call; each recursive call is added to the stack, and completion involves popping the call. This implicit stack management simplifies dealing with recursion's nested nature .

You might also like