Chapter 4 - Stacks
Chapter 4 - Stacks
1
Introduction
• Stacks are linear lists.
• All deletions and insertions occur at one end of the stack
known as the TOP.
• Data going into the stack first, leaves out last.
• This is known as LIFO data structures( the last element
put into the list will be the first element we take out of
the list).
− Last-In, First-Out ("LIFO")
• Analogy
– A stack of dishes in a cafeteria
2
More Analogies
3
Abstract data type: Stack
• There are many times where it is useful to use
a list in a way where we always add to the
end, and also always remove from the end.
• Stack: a more restricted List with the
following
constraints:
− Elements are stored by order of insertion from
"bottom" to "top“.
− Items are added to the top.
− Only the last element added onto the stack
(the top element) can be accessed or
removed.
4
Abstract data type: Stack…
• Goal: every operation on a stack should be O(1).
– Stacks are straightforward to implement in
several different ways, and are very useful.
• Operations on a stack
– push: add an element to the top.
– pop: remove and return the element at the top.
5
Push & Pop Operations
8
Stack … (continued)
Stacks in computer science
• The lowly stack is one of the most important data
structures in all of computer science
– Function/method calls are placed onto a stack.
– Compilers use stacks to evaluate expressions.
– Stacks are great for reversing things, matching up
related pairs of things, and backtracking algorithms.
– Stack programming problems:
Reverse letters in a string, reverse words in a line, or
reverse a list of numbers.
Find out whether a string is a palindrome.
Examine a file to see if its braces { } and other
operators match.
9
Stack … (continued)
• Stacks structures are usually implemented using
arrays or linked lists.
10
Array Based Stack Implementation
• Stacks can be represented in memory using
arrays.
• We can declare an array named as STACK.
• We also use TOP variable to represent top most
element of stack.
• Finally a variable MAX_STACK, which
gives maximum number of elements that can be
stored in stack.
11
Array-based Stacks
15
Linked list Implementation: Push
bool isEmpty(){
return (topPtr == NULL);
}
void push(dataType newItem) {
// create a new node
StackNode *newPtr = new StackNode;
// set data portion of new node
newPtr->item = newItem;
// insert the new node
newPtr->next = topPtr;
topPtr = newPtr;
}
16
Linked list Implementation: Pop
dataType pop() {
if (isEmpty())
cout<<“Stack is empty…!”;
// not empty; retrieve and delete top
else{
stackTOp = topPtr->item;
StackNode *temp = topPtr;
topPtr = topPtr->next;
// return deleted node to system
temp->next = NULL; // safeguard
delete temp;
return stackTOp;
} 17
}
Comparing Implementations
• An array-based implementation.
– Prevents the push operation from adding an
item to the stack if the stack’s size limit has
been reached.
• A pointer-based implementation.
– Does not put a limit on the size of the stack.
18
Applications of Stack
Variable declaration
Function Calling
Reversing Data
Converting Decimal to Binary
Evaluation of Algebraic expression
Converting Infix to Postfix
……
19
Variable declaration
void main()
{
int i, n;
for(i=0;i<=10;i++)
{
int m;
cin>>n; Used to hold
cin>>m; m variables when
cout<<m*n; n declared
} i
cout<<n;
}
20
Function Calling
void main(){
func1();
func2();}
void func1(){ Func3()
cout<<“Hello”; Func1() Func1()
func3(); Main() Main() Main()
}
void func2(){ 1 2 3 4
cout<<“Hi”;
}
void func3(){ Func1() Func2()
cout<<“Hey”; Main() Main() Main()
}
5 6 7 8
}
Note : The one that is found on the top of the stack is currently
executed. When empty stack remain, the program will halt. 21
Reversing Data
We can use stacks to reverse data.
(example: files, strings).
Very useful for finding palindromes.
Consider the following pseudo code:
1)read (data)
2)loop (data not EOF and stack not full)
1) push (data)
2) read (data)
3)Loop (while stack notEmpty)
1) pop (data)
2) print (data)
22
Converting Decimal to Binary
Consider the following pseudo code:
– Read (number)
– Loop (number > 0)
1) digit = number modulo 2
2) print (digit)
3) number = number / 2
• The problem with this code is that it will print the
binary number backwards.
Example: 19 becomes 11001000 instead of 00010011
• To remedy this problem, instead of printing the
digit right away, we can push it onto the stack.
• Then after the number is done being converted, we
pop the digit out of the stack and print it. 23
Evaluation of Algebraic Expressions
• 4+5*5
• Simple calc. 45
• Scientific calc. 29
Mathematical Expression C++ Expression
26
Post Order Traversal, Binary Tree
Infix: A – C / 5 * 2 + D * 5 % 4
Visiting principle: LRP ( Left-Right-Parent)
(Recursive)
+
- %
A * * 4
/ 2 D 5
C 5
Postfix: A C 5 / 2 * - D 5 * 4 % + 27
Postfix Expression Evaluating
Algorithm
• An algorithm exists to evaluate postfix expressions
using a stack.
• The single value on the stack is the desired result.
• Binary operators: +, -, *, /, etc.,
• Unary operators: unary minus, square root, sin, cos,
exp, etc.,
28
Postfix Evaluation
Psuedocode:
Operand: push
Operator: pop 2 operands for binary operator and 1
operand for unary operator, do the
math, push result back onto stack
123+*
PostfixStack( bot -> top )
• 123+*
• 23+* 1
• 3+* 12
• +* 123
• * 1 5 // 5 from 2 + 3
• 5// 5 from 1 * 5 29
initialize stack to empty;
while (not end of postfix expression) {
get next postfix item;
if (item is value)
push it onto the stack;
else if (item is binary operator) {
pop the stack to x;
pop the stack to y;
perform y operator x;
push the results onto the stack;
}
else if (item is unary operator) {
pop the stack to x;
perform operator(x);
push the results onto the stack
} 30
}
Example: 6 5 2 3 + 8 * + 3 + *
• Push items 6 through 3 6523+8*+3+*
• Next 8 is pushed
• Next item is * :
31
(8, 5 popped, 40 pushed)
6523+8*+3+*
• Next the operator + followed by 3:
32
Converting Infix to Postfix
• Convert A + B * C to postfix form:
A+B*C Infix Form
A + (B * C) Parenthesized expression
A + (B C *) Convert the multiplication
A (B C *) + Convert the addition
ABC*+ Postfix form
Rules:
• Parenthesize from left to light, higher precedence
operators parenthesized first.
• The sub-expression (part of expression), which has
been converted into postfix, is treated as single
operand.
• Once the expression is converted to postfix form,
remove the parenthesis. 33
Example: A + [ (B + C) + (D + E) * F ] / G
A + { [ (BC +) + (DE +) * F ] / G}
A + { [ (BC +) + (DE + F *] / G}
A + { [ (BC + (DE + F * +] / G}
A + [ BC + DE + F *+ G / ]
ABC + DE + F * + G / +
36
Example 2: A*B-(C+D)+E
InfixStack(bottom->top)Postfix
A*B-(C+D)+Eemptyempty
• *B-(C+D)+EemptyA
• B-(C+D)+E*A
• -(C+D)+E*AB
• -(C+D)+EemptyAB*
• (C+D)+E-AB*
• C+D)+E-(AB*
• +D)+E-(AB*C
• D)+E-(+AB*C
• )+E-(+AB*CD
• +E-AB*CD+
• +EemptyAB*CD+-
• E+AB*CD+-
• +AB*CD+-E
• emptyAB*CD+-E+
37
Example 3: a+b*c+(d*e+f)*g
InfixStack(bottom->top)Postfix
a+b*c+(d*e+f)*gemptyempty
• +b*c+(d*e+f)*gemptya
• b*c+(d*e+f)*g+a
• *c+(d*e+f)*g+ab
• c+(d*e+f)*g+*ab
• +(d*e+f)*g+*abc
• +(d*e+f)*g+abc*
• +(d*e+f)*gemptyabc*+
• (d*e+f)*g+abc*+
• d*e+f)*g+(abc*+
• *e+f)*g+(abc*+d
• e+f)*g+(*abc*+d
• +f)*g+(*abc*+de
• f)*g+(+abc*+de*
• )*g+(+abc*+de*f
• *g+abc*+de*f+
• g+*abc*+de*f+
• +*abc*+de*f+g
• emptyabc*+de*f+g*+ 38