0% found this document useful (0 votes)
16 views51 pages

Data Structure Stacks (C++)

The document provides an overview of stacks, a data structure that follows the Last In First Out (LIFO) principle, detailing its operations such as Push and Pop. It explains how stacks can be represented using linear arrays or linked lists and includes specifications for stack operations and exceptions. Additionally, it discusses the application of stacks in evaluating arithmetic expressions using infix, prefix, and postfix notations.
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)
16 views51 pages

Data Structure Stacks (C++)

The document provides an overview of stacks, a data structure that follows the Last In First Out (LIFO) principle, detailing its operations such as Push and Pop. It explains how stacks can be represented using linear arrays or linked lists and includes specifications for stack operations and exceptions. Additionally, it discusses the application of stacks in evaluating arithmetic expressions using infix, prefix, and postfix notations.
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/ 51

Data Structure & Algorithm

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

• Two basic operations are associated


with Stack
– Push : Insert an element into a stack
– Pop : Delete an element from a stack
6
Stack
• Stores a set of elements in a particular
order

• Stack principle:
LAST IN FIRST OUT= LIFO
• It means: the last element inserted is the first
one to be removed

• Which is the first element to pick up?

7
Representation of Stack
Stack can be represented in two
different ways :

[1] Linear ARRAY

[2] One-way Linked list

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

const int MAX_ITEMS = 5;

class FullStack
{}; // Exception class thrown by Push when stack is full.
class EmptyStack
{}; // Exception class thrown by Pop and Top when stack is empty.

template <class ItemType>


class StackType
{
public:
StackType();
bool IsFull();
bool IsEmpty();
void MakeEmpty();
void Push(ItemType);
void Pop();
ItemType Top();
private:
int top;
ItemType items[MAX_ITEMS];
};
#endif // STACKTYPE_H_INCLUDED

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--;

template <class ItemType> template <class ItemType>


bool StackType<ItemType>::IsFull() ItemType StackType<ItemType>::Top()
{ {
return (top == MAX_ITEMS-1); if (IsEmpty())
}
O(1)
throw EmptyStack();
return items[top]; O(1)
}

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

[1] If TOP = -1, Then print Underflow and Exit


[2] Set ITEM= STACK[TOP]
[3] TOP--
[4] Exit

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

 Infix notation: The operator symbol is placed between its two


operands. Example: A+B, A-B, A*B, A/B

 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/

 This notation is also known as Reverse Polish notation.


 One never needs parentheses to determine the order of the operations

in any arithmetic expression written in reverse Polish notation.


 The computer usually evaluates an arithmetic expression written in infix
notation in two steps. First, it converts the expression to postfix
notation, and then it evaluates the postfix expression. In each step,
the stack is the main tool that is used to accomplish the given task.

21
Data Structures (Operator Precedence)

 Two operators of same priority can’t stay together.


 Higher priority operator will not stay in the stack when lower priority
operator will be inserted.
 (…..) => pop all the operators from stack and place them in the
postfix.

22
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:
 Push “(” onto stack and then add “)” to the end of Q. Thus, Q becomes

Q: A + ( B * C - ( D / E ↑ F ) * G ) * H )
 Start scanning. The following table shows the status of STACK and of

the string P as each element of Q is scanned.

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.

1. Push “(” onto STACK and add “)” to the end of Q.


2. Scan Q from left to right and repeat steps 3 to 6 for each element of
Q until the STACK is empty.
3. If an operand is encountered, add it to P.
4. If a left parenthesis is encountered, push it onto
STACK.

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

Example: Consider the postfix expression, 2 10


+ 9 6 - /, which is (2 + 10) / (9 - 6) in infix,
the result of which is 12 / 3 = 4.
The following is a trace of the postfix evaluation
algorithm for the postfix expression:
Data Structures
 Example 6.6: Find the value of the following arithmetic expression P
written in postfix notation:
P: 5, 6, 2, +, *, 12, 4, /, -

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.

1. Add a right parenthesis “)” at the end of P.


2. Scan P from left to right and repeat Steps 3 and 4 for each element of P until the
sentinel ")" is encountered.
3. If an operand is encountered, put it on STACK.
4. If an operator is encountered, then:
a) Remove the two top elements of STACK, where A is the top
element and B is the next-to-top element.
b) Evaluate B A.
c) Place the result of (b) back on STACK.
[End of If structure]
[End of Step 2 loop.]
5. Set VALUE equal to the top element on STACK.
6. Exit.

33
Data Structures
 Recursion

 A procedure is called a recursive procedure if it contains a Call


statement to itself.
 A recursive procedure must have the following two properties:

 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.

1. If N = 0, then: Set FACT := 1, and Return.


2. Set FACT := 1.
3. Repeat for K = 1 to N.
Set FACT := K*FACT.
[End of loop.]
4. Return.

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.

1. If N = 0, then: Set FACT := 1, and Return.


2. Call FACTORIAL(FACT, N — 1).
3. Set FACT := N*FACT.
4. Return.

37
Data Structures
 Fibonacci Sequence

The Fibonacci sequence (usually denoted by F0, F1, F2, . …….) is as


follows:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ....

That is, F0 = 0 and F1 = 1 and each succeeding term is the sum of the two
preceding terms.

Definition: (Fibonacci Sequence)


a) If n = 0 or n = 1, then Fn = n.
b) If n > 1, then Fn = Fn-2 + Fn-1

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.

 Use of recursion in an algorithm has both advantages and disadvantages.


 The main advantage is usually simplicity.
 The main disadvantage is often that the algorithm may require large amounts
of memory if the depth of the recursion is very large.
 Recursive isn’t always better. This takes O(2n) steps. Unusable for large n.
 Iterative approach is “linear”; it takes O(n) steps.

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()

Time: 0 Time 1: Time 2: Time 3: Time 4:


Empty Stack Push: main() Push: square()Pop: square() Pop: main()
returns a value.returns a value.
method exits. method exits.
Stacks and Recursion
Each time a method is called, you push the
method on the stack.
Each time the method returns or exits, you
pop the method off the stack.
If a method calls itself recursively, you just
push another copy of the method onto the
stack.
We therefore have a simple way to visualize
how recursion really works.
Stacks and Recursion in Action

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()

Time 2: Time 3: Time 4: Time 5: Time 6: Time 7:


Push: Push: fact(2) Push: fact(1) Pop: fact(1) Pop: fact(2) Pop: fact(3)
fact(3) returns 1. returns 2. returns 6.

Inside findFactorial(3): Inside findFactorial(2): Inside findFactorial(1):


if (number <= 1) return 1; if (number <= 1) return 1; if (number <= 1) return
else return (3 * else return (2 * 1;
else return (1 * factorial
factorial (2)); factorial (1));
(0));
Example Using Recursion:
The Fibonacci Series

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 )

 fibonacci(0) and fibonacci(1) are base cases


Golden ratio (golden mean)

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

You might also like