Data Structures & Algorithms
Stack & Its Applications
Recap
▪ Doubly Linked List
▪ Circular Linked Lists
Lecture 6: Stack & Its 2
Today’s Lecture
▪ Stack
▪ Practical applications
► Stacks in validating expressions
► Infix to Postfix conversion
Lecture 6: Stack & Its 3
Stack
Definition:
▪ Conceptually, a stack is a data structure that allows
adding and removing elements in a particular order
► More specifically, in an order such that items can be
inserted or deleted to the collection of already inserted
items from one end only, called the top of the stack
Lecture 6: Stack & Its 4
Stack
▪ Stack is said to have “First In, Last Out" (FILO) or “Last
In, First Out” (LIFO) behaviour meaning that the first
item added to a stack will be the last item removed
from a stack
▪ Example:
► Which is the first coin to pick up from
the stack of gold coins?
Lecture 6: Stack & Its 5
Basics of stack
▪ Size: The number of elements on the stack
▪ Top: Points to the top most element on the stack. This
refers to NULL if stack is empty or size = 0
Because we think of stacks in terms of the physical
analogy,
we usually draw them vertically (so the top is really on top)
Lecture 6: Stack & Its 6
Stack Operations
▪ Primarily two operations performed on one end only
► Push: Add an item on the top of stack
► Pop: Remove an item at the top of stack
Lecture 6: Stack & Its 7
Stack Operations
▪ Push Concerns
► What if when the stack is full?
▪ Pop Concerns
► What if the stack is empty
Solution:
▪ Before any push, check if the stack is already filled or not
► If it is filled then generate error message e.g., Stack
Overflow
▪ Before pop, check if stack is not already empty
Lecture 6: Stack & Its 8
Stack Operations
push(item) // Push an item onto the stack
pop( ) // Pop the top item off the stack
isEmpty() // Return true if stack is empty
isFull() // Return true if stack is full
top( ) or peek() // Return value of top item
Lecture 6: Stack & Its 9
Applications
▪ Real life
► Stack of trays in cafeteria
► Piles of books in library
▪ Computer Science
► Compilers use stacks to evaluate expressions & syntax
parsing
► Program execution stack
► Undo operations
► Expression conversion
► Infix to post-, pre-fix and vice versa
► Tower of Hanoi
► And many more …
Lecture 6: Stack & Its 10
Choice of implementation
▪ Array based: Stack Maximum stack size is known
ahead of time
▪ Linked List based: Stack Maximum stack size
unknown
Lecture 6: Stack & Its 13
Array based stack
▪ When using an array to implement a stack
► The array's first element should represent the bottom of
the stack
► The last occupied location in the array represents the
stack's top
▪ This avoids shifting of elements of the array when we
push or remove elements from stack
Lecture 6: Stack & Its 14
Array based stack
▪ Allocate an array of some size (pre-defined)
► Maximum N elements in stack
▪ Bottom stack element stored at element 0
▪ Last index in the array is the top
▪ Increment top when one element is pushed, similarly
decrement after each pop
Lecture 6: Stack & Its 15
Array based stack operations
int stack[size]; int Pop() {
int top = -1; int element = -1;
If (!isEmpty()) {
void Push(int element) { element = stack[top];
if (!isFull()) { stack[top--] = -1;
stack[++top] = element; }
} return element;
} }
bool isFull() { bool isEmpty() {
return top==size-1; return top<0;
} }
Lecture 6: Stack & Its 16
Linked List based implementation
▪ LIFO
► Push = Insert at head
► Pop = Remove at head
► IsEmpty = Empty List
► Clear = Delete List
Lecture 6: Stack & Its 17
Linked List based implementation
class node class stack
{ {
public: int size;
int value;
node* top;
node* next;
}; //class node public:
stack() {
size=0;
top=NULL;
} //default constructor
void push(int);
bool pop();
bool isEmpty(); };
Lecture 6: Stack & Its 18
Linked List based implementation
void stack::push(int el) void main ()
{ {
node *temp; ...
temp =new node; stack();
if (top==NULL) { [Link](5);
temp->next =NULL; ...
} }
else {
temp->next =top;
}
temp->value=el;
top=temp;
size++; }
Lecture 6: Stack & Its 19
Linked List based implementation
int stack::pop() bool stack::isEmpty()
{ int d;
{
if(isEmpty()) {
if(getStackSize()==0)
cout<<"\nStack is Empty\n"; return true;
return 0;
} return false;
else { }
Node *temp = top;
top=top->next;
d=temp->value;
delete temp;
size--; }
return d; }
Lecture 6: Stack & Its 20
Today’s Lecture
▪ Stack
▪ Practical applications
► Stacks in validating expressions
► Infix to Postfix conversion
Lecture 6: Stack & Its 21
Algebraic expression
▪ An algebraic expression is a legal combination of
operands and the operators
▪ Operand is the quantity (unit of data) on which a
mathematical operation is performed
► E.g., operand may be a variable like x, y, z or a constant
like 5, 4,0,9,1 etc.
▪ Operator is a symbol which signifies a mathematical or
logical operation between the operands
► Example of familiar operators include +,-,*, /, ^
▪ Considering these definitions of operands and
operators, an example of expression may be x+y*z
Lecture 6: Stack & Its 22
Stacks in problem solving
▪ Consider a mathematical expression that includes
several sets of nested parenthesis, e.g.,
( x + (y – (a +b)) )
▪ We want to ensure that parenthesis are nested
correctly and the expression is valid
Validation
▪ There is an equal number of right and left parentheses
▪ Every right parenthesis is preceded by a matching left
parenthesis (A+B) * C Valid
A + B) Invalid
(A+B] Invalid
Lecture 6: Stack & Its 23
Rules
▪ Each left parentheses is the opening scope while each
right parenthesis is a closing scope
▪ Parentheses count = 0 at the end means that no
scopes have been left open and left and right
parentheses exactly match
((A+B) (A*B)
122221 11110
Invalid expression Valid expression
Lecture 6: Stack & Its 24
Parsing parenthesis
▪ We have seen use of stack in validation of expression
using only ‘(‘ and ‘)’ scope delimiter
▪ Let us change the problem slightly
► Three different kinds of scope delimiters exist
e.g., { x + (y – [a +b]) }
► The scope ender must be of same type as scope opener
► It is necessary to keep track of not only the count of
scope but also the types
► A stack may be used to keep track of the types of
scopes encountered
Lecture 6: Stack & Its 25
Stacks in validating expression
▪ Whenever a scope opener is encountered
► it is pushed into the stack
▪ Whenever a scope ender is encountered,
► The stack is examined
► If the stack is empty, the scope ender does
not have a matching opener and string is
invalid
► If stack is not empty, we pop an item and check if
it corresponds to scope ender
- If match occurs we continue,
- otherwise the expression is invalid
▪ At the end of the string the stack must be empty
Lecture 6: Stack & Its 26
Valid = true
S = the empty stack // array of chars say char s[100]
While (we have not read the entire string) {
read the next symbol (symb) of the string;
if (symb == ‘(‘ || symb == ‘[‘ || symb == ‘{‘)
push (s, symb);
Pseudo code
if (symb == ‘)‘ || symb == ‘]‘ || symb == ‘}‘)
if (IsEmpty(s))
valid = false;
else {
I = pop (s);
if ( I is not the matching opener of symb)
valid = false;
}// end of else
} //end while
If (valid)
cout << “Valid String” << endl;
Else
tures & Algorithms
Lecture 6: Stack & Its Applications 27
cout << “not a valid string”
Stacks in validating expression
{ x + (y – [a +b]) }
( ( (
{ { { { {
1 2 3 4 5 6 7
Lecture 6: Stack & Its 28
Operator Priorities
▪ How do you figure out the operands of an operator?
► a+b*c
► a*b+c/d
▪ This is done by assigning operator priorities
► priority(*) = priority(/) > priority(+) = priority(-)
▪ When an operand lies between two operators, the
operand is associated with the operator that has the
higher priority
Lecture 6: Stack & Its 29
Tie breaker
▪ When an operand lies between two operators that
have the same priority, the operand is associated with
the operator on the left
► a+b-c
► a*b/c/d
Lecture 6: Stack & Its 30
Infix, Prefix & Postfix expressions
▪ INFIX: Expressions in which operands surround the
operator,
► e.g., x+y, 6*3 … etc.
▪ PREFIX: Expressions in which operator comes before
the operands, e.g., +xy, *+xyz etc.
► Also known as Polish Notation (PN)
▪ POSTFIX: Expressions in which operator comes after
the operands, e.g., xy+, xyz+* etc.
► Also known as Reverse Polish Notation (RPN)
Lecture 6: Stack & Its 31
Prefix & Postfix notations, why to use?
▪ Why to use these weird looking PREFIX and POSTFIX
notations when we have simple INFIX notation?
► INFIX notations are not as simple as they seem
specially while evaluating them
► To evaluate an infix expression we need to consider
operators’ Priority and Associative property
-E.g., expression 3+5*4 can either be evaluated
as 32 i.e., (3+5)*4 or 23 i.e., 3+(5*4)
▪ To solve this problem Precedence or Priority of the
operators were defined to govern the evaluation order
i.e., operator with higher precedence is applied before
an operator with lower precedence
Lecture 6: Stack & Its 32
Infix expression is hard to parse
▪ Need operator priorities, tie breaker, and delimiters
which makes computer evaluation more difficult than is
necessary
▪ Postfix and prefix expression forms do not rely on
operator priorities, a tie breaker, or delimiters
► I.e., need not to consider the Priority and
Associative property (order of brackets)
- E.g. x/y*z becomes */xyz in prefix and xy/z* in
postfix
► So it is easier to evaluate expressions that are in these
forms
Lecture 6: Stack & Its 33
Prefix & Postfix notations, why to use?
▪ Compilers need to generate assembly code in which
one operation is executed at a time and the result is
retained for other operations
▪ Therefore, all expressions have to be broken down
unambiguously into separate operations and put into
their proper order
▪ That is where Polish notation is useful as it allows us to
create an expression tree, which imposes an order on
the execution of operations
Lecture 6: Stack & Its 34
Expression tree
Prefix Infix Postfix
Lecture 6: Stack & Its 35
Infix to Postfix
Example:
A+B*C
A+(B*C) Parentheses for emphasis
A+(BC*) Convert the multiplication, Let D=BC*
A+D Convert the addition
AD+
ABC*+ Postfix Form
Lecture 6: Stack & Its 36
Examples of Infix to Post- & Prefix
Infix PostFix Prefix
A+B AB+ +AB
(A+B) * (C + D) AB+CD+* *+AB+CD
A-B/(C*D^E) ABCDE^*/- -A/B*C^DE
Lecture 6: Stack & Its 37
More examples
Lecture 6: Stack & Its 38
Infix to Postfix conversion algorithm
▪ Create an empty stack for keeping operators
▪ Create an empty list for output
▪ Scan each element of input expression from left to right
► If the element is an operand, append it to the end of the output list
► If the element is a left parenthesis, push it on the stack
► If the element is a right parenthesis, apply pop operation to the
stack until the corresponding left parenthesis is removed & append
each operator to the end of the output list
► If the element is an operator, *, /, +, or -, push it on the stack.
However, first remove any operators already on the stack that
have higher or equal precedence and append them to the output
list
▪ When the input expression has been completely processed, check the
stack. Any operators still on the stack can be removed and appended to
the end of the output list
Lecture 6: Stack & Its 39
Suppose we want to convert 2*3/(2-1)+5*3 into Postfix form,
Expression Stack Output
2 Empty 2
* * 2
3 * 23
/ / 23*
( /( 23*
2 /( 23*2
- /(- 23*2
1 /(- 23*21
) / 23*21-
+ + 23*21-/
5 + 23*21-/5
* +* 23*21-/53
3 +* 23*21-/53
Empty 23*21-/53*+
Lecture 6: Stack & Its 40
Evaluating Postfix expression
▪ Each operator in a postfix string refers to the previous
two operands in the string
▪ Suppose that each time we read an operand we push it
into a stack. When we reach an operator, its operands
will then be the top two elements on the stack
▪ We can then pop these two elements, perform the
indicated operation on them, and push the result back
onto the stack so that it will be available for use as an
operand of the next operator
Lecture 6: Stack & Its 41
Algorithm to evaluate Postfix expression
1) Create an empty stack
2) Scan the elements of Postfix expression from left to right
3) If the element is an operand, push the value onto the
stack
4) If the element is an operator, *, /, +, or -
▪ Pop the stack twice. The first pop is the second
operand and the second pop is the first operand
▪ Perform the arithmetic operation & push the result
back on the stack
4) When the input expression has been completely
processed, apply pop operation onto the stack to
return the computed value
Lecture 6: Stack & Its 42
Algorithm to evaluate Postfix expression
WHILE more input items exist
{
If symb is an operand
then push (stk,symb) // stk is the stack used
else //symbol is an operator
{
Opnd1=pop(stk);
Opnd2=pop(stk);
Value = result of applying symb to opnd1 & opnd2
Push(stk,value);
} //End of else
} // end while
Result = pop (stk);
Lecture 6: Stack & Its 43
Algorithm to evaluate Postfix expression
Lecture 6: Stack & Its 44
Question
▪ Evaluate following Postfix expression:
623+-382/+*2^3+
Final answer is
a) 49
b) 51
c) 52
d) 7
e) None of these
Lecture 6: Stack & Its 45