Data Structure Stacks (C++)
Data Structure Stacks (C++)
CSE-225
Lecture-11: Stack
• There are certain frequent situations in
computer science when one wants
to restrict insertion and deletion so that they
can take place only at the beginning or at the
end not in the middle.
– Stack
– Queue
2
Stack
3
Stack
A list
Data items can be added and deleted
Maintains Last In First Out (LIFO) order
An Example of a Stack
top 2
top 8 8
top 1 1 1
Push(8) Push(2)
7 7 7
2 2 2
pop()
top 8
top 1
1
top 7 7 pop()
2
pop() 7
2
2
Stack
• A Stack is a list of elements in which an
element may be inserted or deleted only at
one end, call top of the Stack
• Stack principle:
LAST IN FIRST OUT= LIFO
• It means: the last element inserted is the first
one to be removed
7
Representation of Stack
Stack can be represented in two
different ways :
8
Array Representation of Stack
STACK
A B C
0 1 2 3 4 5 6 7
TOP 2 MAXSTK 7
TOP = -1 or TOP = NULL
will indicates that the stack is empty
9
Specification of StackType
Structure: Elements are added to and removed from the top of
the stack.
Definitions (provided by user):
MAX_ITEMS Maximum number of items that might be on the
stack.
ItemType Data type of the items on the stack.
Operations (provided by the ADT):
MakeEmpty
Function Sets stack to an empty state.
Postcondition Stack is empty.
Boolean IsEmpty
Function Determines whether the stack is empty.
Precondition Stack has been initialized.
Postcondition Returns true if stack is empty and false otherwise.
Boolean IsFull
Function Determines whether the stack is full.
Precondition Stack has been initialized. 10
Specification of StackType
Push(ItemType newItem)
Function Adds newItem to the top of the stack.
Precondition Stack has been initialized.
Postcondition If (stack is full), exception FullStack is thrown, else
newItem is at the top of the stack.
Pop()
Function Removes top item from the stack.
Precondition Stack has been initialized.
Postcondition If (stack is empty), exception EmptyStack is thrown,
else top element has been removed from stack.
ItemType Top()
Function Returns a copy of the top item on the stack.
Precondition Stack has been initialized.
Postcondition If (stack is empty), exception EmptyStack is thrown,
else a copy of the top element is returned.
11
stacktype.h
#ifndef STACKTYPE_H_INCLUDED
#define STACKTYPE_H_INCLUDED
class FullStack
{}; // Exception class thrown by Push when stack is full.
class EmptyStack
{}; // Exception class thrown by Pop and Top when stack is empty.
12
stacktype.cpp
template <class ItemType>
#include "StackType.h" void StackType<ItemType>::Push(ItemType
template <class ItemType> newItem)
{
StackType<ItemType>::StackType() if( IsFull() )
{ throw FullStack();
top = -1; top++;
} items[top] = newItem;
template <class ItemType> }
bool StackType<ItemType>::IsEmpty()
{ template <class ItemType>
return (top == -1); void StackType<ItemType>::Pop()
} {
void StackType<ItemType>::MakeEmpty() if( IsEmpty() )
{ throw EmptyStack();
top = -1; top--;
} }
template <class ItemType> template <class ItemType>
bool StackType<ItemType>::IsFull() ItemType StackType<ItemType>::Top()
{ {
return (top == MAX_ITEMS-1); if (IsEmpty())
} throw EmptyStack();
return items[top];
}
13
stacktype.cpp
#include "StackType.h" template <class ItemType>
template <class ItemType> void StackType<ItemType>::Push(ItemType
newItem)
StackType<ItemType>::StackType() {
O(1)
{ if( IsFull() )
top = -1; throw FullStack();
}
template <class ItemType>
top++;
items[top] = newItem;
O(1)
bool StackType<ItemType>::IsEmpty() }
O(1)
{ template <class ItemType>
return (top == -1); void StackType<ItemType>::Pop()
} {
void StackType<ItemType>::MakeEmpty() if( IsEmpty() )
{ throw EmptyStack(); O(1)
}
top = -1;
O(1) }
top--;
14
PUSH Operation
Perform the following steps to PUSH an ITEM onto
a Stack
[1] If TOP = MAXSTK, Then print: Overflow,
Exit [ Stack already filled]
[2] Set TOP++
[3] Set STACK[TOP] = ITEM
[Insert Item into new TOP Position]
[4] Exit
1
0
POP Operation
Delete top element of STACK and assign it to the variable ITEM
16
Push Operation
void push(int num){
if(isFull()){
cout<<"STACK is FULL."<<endl;
return;
}
++TOP;
STACK[TOP]=num;
cout<<num<<" has been inserted."<<endl;
}
POP Operation
• POP operation is accomplished by deleting
the node pointed to by the TOP pointer
[Delete the first node in the list]
18
Pop operation
//pop - to remove item
void pop(){
int temp;
if(isEmpty()){
cout<<"STACK is EMPTY."<<endl;
return;
}
temp=STACK[TOP];
TOP--;
cout<<temp<<" has been deleted."<<endl;
}
Data Structures
ARITHMETIC EXPRESSIONS; POLISH NOTATION
Prefix notation: The operator symbol is placed before its two operands.
Example: +AB, -AB, *AB, /AB
This notation is also known as Polish notation, named after the
Polish mathematician Jan Lukasiewicz.
The fundamental property of Polish notation is that the order in
which the operations are to be performed is completely determined
by the positions of the operators and operands in the expression.
Accordingly, one never needs parentheses when writing expressions
in Polish notation.
20
Data Structures
ARITHMETIC EXPRESSIONS; POLISH NOTATION
Postfix notation: The operator symbol is placed after its two operands.
Example: AB+, AB-, AB*, AB/
21
Data Structures (Operator Precedence)
22
Data Structures
Example 6.7: Transform the following arithmetic infix expression Q
Q: A + ( B * C - ( D / E ↑ F ) * G ) * H )
Start scanning. The following table shows the status of STACK and of
23
Data Structures
Example 6.7: Transform the following arithmetic infix expression Q
into its equivalent postfix expression P:
Q: A + (B*C - (D /E ↑ F)*G)*H)
Solution:
Symbol Scanned STACK Expression, P
A ( A
+ (+ A
( (+( A
B (+( A B
* (+( * A B
C (+( * A B C
- (+( - A B C *
( (+( - ( A B C *
24
Data Structures
Example 6.7: Transform . . . . . postfix expression P:
Q: A + (B*C - (D /E ↑ F)*G)*H)
Symbol Scanned STACK Expression, P
D (+( - ( A B C * D
/ (+( - ( / A B C * D
E (+( - ( / A B C * D E
↑ (+( - ( / ↑ A B C * D E
F (+( - ( / ↑ 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
) (+ 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 * +
25
Data Structures
Solved Problem 6.10: Transform the following arithmetic infix
expression Q into its equivalent postfix expression P:
Q: ((A + B)*D) ↑ (E-F)
Solution:
Push “(” onto stack and then add “)” to the end of Q. Thus, Q becomes
Q: ((A + B) * D) ↑ (E-F) )
Start scanning. The following table shows the status of STACK and of
the string P as each element of Q is scanned.
26
Data Structures
Solved Problem 6.10: Transform . . . postfix expression P:
Q: ((A + B)*D) ↑ (E-F))
Symbol Scanned STACK Expression, P
( ((
( (((
A ((( A
+ (((+ A
B (((+ A B
) (( A B+
* ((* A B+
D ((* A B+D
) ( A B+D*
↑ (↑ A B+D*
( (↑( A B+D*
E (↑( A B+D*E
- (↑(- A B+D*E
F (↑(- A B+D*EF
) (↑ A B+D*EF-
) A B+D*EF-↑
27
Data Structures
Algorithm 6.6: Write an algorithm that transforms the infix expression
into its equivalent postfix expression.
POLISH (Q, P)
Suppose Q is an arithmetic expression written in infix notation. This
algorithm finds the equivalent postfix expression P.
28
Data Structures
Algorithm 6.6: Write an algorithm that transforms the infix expression
into its equivalent postfix expression.
5. If an operator is encountered, then
(a) Repeatedly pop from STACK and add to P each
operator (on the top of STACK) which has the same
precedence as or higher precedence than .
(b) Add to STACK.
[End of if structure]
6. If a right parenthesis is encountered, then
(a) Repeatedly pop from STACK and add to P each
operator (on the top of STACK) until a left parenthesis
is encountered.
(b) Remove the left parenthesis.
[End of if structure]
[End of Step 2 loop]
7. Exit.
29
Application of Stacks - Evaluating Postfix Expression
Solution:
- First we add a sentinel right parenthesis at the end of P:
P: 5, 6, 2, +, *, 12, 4, /, -, )
(1) (2) (3) (4) (5) (6) (7) (8) (9) (10)
- Start scanning from left to right. The following table shows the contents of
STACK as each element of P is scanned. The final number in STACK, 37,
which is assigned to VALUE when the sentinel ")" is scanned, is the value
of P.
31
Data Structures
Example 6.6: Find the value of the following arithmetic expression P
written in postfix notation:
P: 5, 6, 2, +, *, 12, 4, /, -, )
(1) (2) (3) (4) (5) (6) (7) (8) (9) (10)
Solution:
Symbol Scanned STACK
(1) 5 5
(2) 6 5, 6
(3) 2 5, 6, 2
(4) + 5, 8
(5) * 40
(6) 12 40, 12
(7) 4 40, 12, 4
(8) / 40, 3
(9) - 37
(10) )
32
Data Structures
Algorithm 6.5: Write an algorithm that finds the value of an arithmetic
expression written in postfix notation.
This algorithm finds the VALUE of an arithmetic expression P written in postfix notation.
33
Data Structures
Recursion
There must be certain criteria, called base criteria, for which the
procedure does not call itself.
Each time the procedure does call itself, it must be closer to the base
criteria.
34
Data Structures
Recursion
Example 6.9: Calculate 4! using the recursive definition.
Solution: This calculation requires the following nine steps:
1) 4! = 4. 3!
2) 3! = 3. 2!
3) 2! = 2 . 1!
4) 1! = 1 . 0!
5) 0! = 1
6) 1! = 1 . 1 = 1
7) 2! = 2 . 1 =2
8) 3! = 3. 2 = 6
9) 4!=4 . 6 = 24
35
Data Structures
Procedure 6.9A: Write a procedure that calculates N!
FACTORIAL(FACT, N)
This procedure calculates N! and returns the value in the variable FACT.
36
Data Structures
Procedure 6.9B: Write a recursive procedure that calculates N!
FACTORIAL(FACT, N)
This procedure calculates N! and returns the value in the variable FACT.
37
Data Structures
Fibonacci Sequence
That is, F0 = 0 and F1 = 1 and each succeeding term is the sum of the two
preceding terms.
38
Data Structures
Fibonacci Sequence
Procedure 6.10: Write a recursive procedure that finds the nth Fibonacci
number.
FIBONACCI(F1B, N)
This procedure calculates FN and returns the value in the first parameter
FIB.
1. If N = 0 or N = 1, then: Set FIB := N, and Return.
2. Call FIBONACCI(F1BA, N - 2).
3. Call FIBONACCI(FIBB, N - 1).
4. Set FIB := F1BA + FIBB.
5. Return.
39
Data Structures
Recursion vs. Iteration
Roughly speaking, recursion and iteration perform the same kinds of
tasks:
Solve a complicated task one piece at a time, and combine the results.
Emphasis of iteration:
keep repeating until a task is “done”
Emphasis of recursion:
Solve a large problem by breaking it up into smaller and smaller pieces
until you can solve it; combine the results. Example: recursive factorial
function.
40
Data Structures
Recursion vs. Iteration
The function calls itself recursively on a smaller version of the input (n - 1). The
solution to the problem is then devised by combining the solutions obtained
from the simpler versions of the problem.
41
Stacks and Methods
When you run a program, the computer
creates a stack for you.
Each time you invoke a method, the method
is placed on top of the stack.
When the method returns or exits, the
method is popped off the stack.
The diagram on the next page shows a
sample stack for a simple C++ program.
Stacks and Methods
square
()
main() main() main()
count(2
)
count(1 count(1
) )
count(0 count(0 count(0
) ) )
main() main() main() main() …
Time: 0 Time 1: Time 2: Time 3: Time 4: Times 5-8:
Empty Stack Push: main() Push: Push: count(1)
Push: count(2)
Pop everything
count(0)
Inside count(2):
Inside count(0): Inside count(1): print (index); 2
print (index); print (index); 1if (index < 2)
0 if (index < 2) count(index+1);
if (index < 2) count(index+1);This condition now fails!
count(index+1);
Hence, recursion stops,
and we proceed to pop all
functions off the stack.
Stack Short-Hand
Rather than draw each stack like we did last time,
you can try using a short-hand notation.
time stackoutput
time 0: empty stack
time 1: f(4) Level: 1
time 2: f(4), f(3) Level: 2
time 3: f(4), f(3), f(2) Level: 3
time 4: f(4), f(3), f(2), f(1) Level: 4
time 5: f(4), f(3), f(2) LEVEL: 4
time 6: f(4), f(3) LEVEL: 3
time 7: f(4) LEVEL: 2
time 8: empty LEVEL: 1
Factorials
Computing factorials are a classic problem
for examining recursion.
A factorial is defined as follows:
n! = n * (n-1) * (n-2) …. * 1;
For example:
1! = 1 (Base Case)
2! = 2 * 1 = 2
3! = 3 * 2 * 1 = 6
4! = 4 * 3 * 2 * 1 = 24
5! = 5 * 4 * 3 * 2 * 1 = 120
Finding the factorial of 3
fact(1)
1
fact(2) fact(2) fact(2)
2
fact(3) fact(3) fact(3) fact(3) fact(3)
6
main() main() main() main() main() main()
Fibonacci series
Each number in the series is sum of two
previous numbers
e.g., 0, 1, 1, 2, 3, 5, 8, 13, 21…
fibonacci(0) = 0
fibonacci(1) = 1
fibonacci(n) = fibonacci(n - 1) + fibonacci( n – 2 )
49
Recursion vs. Iteration
Iteration
Uses repetition structures (for, while or do…while)
Repetition through explicitly use of repetition
structure
Terminates when loop-continuation condition fails
Controls repetition by using a counter
Recursion
Uses selection structures (if, if…else or switch)
Repetition through repeated method calls
Terminates when base case is satisfied
Controls repetition by dividing problem into simpler
one
50
Recursion vs. Iteration (cont.)
Recursion
More overhead than iteration
More memory intensive than iteration
Can also be solved iteratively
Often can be implemented with only a few lines
of code
51