here

advertisement
STACK
Stack ADT
2




A stack is an abstract data type based on the list
data model
All operations are performed at one end of the list
called the top of the stack (TOS)
“LIFO (for last-in first-out) list” is a synonym for stack
Common operations:
 push(x)
puts the element x on top of the stack
 pop removes the topmost element from the stack.
Java Stack Interface
3
public interface Stack {
public void push(Object x);
public Object pop();
public Object peek();
public boolean isEmpty();
public void clear();
}
From interface to implementation
4

Given that we want to support some interface, the
designer still faces a choice
 What
will be the best way to implement this interface
for my expected type of use?
 Choice of implementation can reflect many
considerations

Major factors we think about
 Speed
for typical use case
 Storage space required
Array implementation of Stack
5
class ArrayStack implements Stack {
max-1
private Object[] array; //Array that holds the Stack
private int index = 0; //First empty slot in Stack
index
4
public ArrayStack(int maxSize)
3
{ array = new Object[maxSize]; }
2
1
public void push(Object x) { array[index++] = x; }
0
public Object pop() { return array[--index]; }
public Object peek() { return array[index-1]; }
public boolean isEmpty() { return index == 0; }
public void clear() { index = 0; }
}
O(1) worstcase time for
each
operation
Question: What can go wrong?
…. What if maxSize is too small?
Linked List Implementation of Stack
6
class ListStack implements Stack {
private Node head = null;
//Head of list that
//holds the Stack
public void push(Object x) { head = new Node(x, head); }
public Object pop() {
O(1) worst-case
time for each
operation (but
constant is
larger)
Node temp = head;
head = head.next;
return temp.data;
}
public Object peek() { return head.data; }
public boolean isEmpty() { return head == null; }
public void clear() { head = null; }
}
head
Note that array
implementation can
overflow, but the
linked list version
cannot
Use of Stack
7




Infix to postfix conversion
Postfix evaluation
Function calls
etc
Infix to postfix
8

When an operand is read, output it

When ( is read, push it

When an operator is read:





If TOS item has higher or equal precedence, repeatedly pop until TOS has an
element of lower precedence or stack empty, then push the operator
If the stack is empty or TOS item has lower precedence, just push it
When ) is found, pop until we find the matching (
( has the lowest precedence when in the stack but has the highest
precedence when in the input
When we reach the end of input, pop until the stack is empty
Example
9
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack:
Output:
Example
10
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: (
Output:
Example
11
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: (
Output: 8
Example
12
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( +
Output: 8
Example
13
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( +
Output: 8 9
Example
14
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( + *
Output: 8 9
Example
15
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( + * (
Output: 8 9
Example
16
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( + * (
Output: 8 9 4
Example
17
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( + * ( +
Output: 8 9 4
Example
18
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( + * ( +
Output: 8 9 4 5
Example
19
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( + * ( + *
Output: 8 9 4 5
Example
20
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( + * ( + *
Output: 8 9 4 5 7
Example
21
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( + * ( +
Output: 8 9 4 5 7 *
Example
22
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( + * (
Output: 8 9 4 5 7 * +
Example
23
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( + * ( +
Output: 8 9 4 5 7 * +
Example
24
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( + * ( +
Output: 8 9 4 5 7 * + 6
Example
25
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( + * (
Output: 8 9 4 5 7 * + 6 +
Example
26
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( + *
Output: 8 9 4 5 7 * + 6 +
Example
27
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: ( +
Output: 8 9 4 5 7 * + 6 + *
Example
28
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: (
Output: 8 9 4 5 7 * + 6 + * +
Example
29
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack:
Output: 8 9 4 5 7 * + 6 + * +
Example
30
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: +
Output: 8 9 4 5 7 * + 6 + * +
Example
31
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: +
Output: 8 9 4 5 7 * + 6 + * + 3
Example
32
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: + *
Output: 8 9 4 5 7 * + 6 + * + 3
Example
33
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: + *
Output: 8 9 4 5 7 * + 6 + * + 3 5
Example
34
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: +
Output: 8 9 4 5 7 * + 6 + * + 3 5 *
Example
35
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack:
Output: 8 9 4 5 7 * + 6 + * + 3 5 * +
Example
36
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: +
Output: 8 9 4 5 7 * + 6 + * + 3 5 * +
Example
37
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack: +
Output: 8 9 4 5 7 * + 6 + * + 3 5 * + 4
Example
38
(8 + 9 * (4 + 5 * 7 + 6)) + 3 * 5 + 4
Stack:
Output: 8 9 4 5 7 * + 6 + * + 3 5 * + 4 +
More Examples
39

Refer to the slides by Otávio Braga linked from the
class website
Postfix evaluation
40




Starting with an empty stack, we scan the postfix
expression from left to right
Each time we encounter an argument, we push it onto
the stack
When we encounter an operator, we pop the stack
twice, remembering the operands popped
We then apply the operator to the two popped
values (with the second as the left operand) and push
the result onto the stack
Example
41

Evaluating 3 4 + 2 *
Postfix to Expression Tree
42
A 2 * 2 A * B * - B 2 * + A B - /
1. Push A
2. Push 2
3. Pop 2
4. Pop A
5. Create tree_1
6. Push tree_1
7. Push 2
8. Push A
9. Pop A
10. Pop 2
11. Create tree_2
12. Push tree_2
13. Push B
14. Pop B
15. Pop tree_2
16. Create tree_3
17. Push tree_3
18. Pop tree_3
19. Pop tree_1
20. Create tree_4
21. Push tree_4
22. Push B
23. Push 2
24. Pop 2
25. Pop B
26. Create tree_5
27. Push tree_5
28. Pop tree_5
29. Pop tree_4
30. Create tree_6
31. Push tree_6
32. Push A
33. Push B
34. Pop B
35. Pop A
36. Create tree_7
37. Push tree_7
38. Pop tree_7
39. Pop tree_6
40. Create tree_8
41. Push tree_8
tree_8
tree_6
tree_4
tree_1
tree_5
tree_3
tree_2
tree_7
Evaluating expression tree
43

If at leaf node (operand node) return the operand’s value

Otherwise:

Evaluate the left sub-tree

Evaluate the right sub-tree

Combine the results from both sub-trees with the operator at root
public static int eval(TreeCell root) {
int left_result, right_result;
if (root.datum is operand) return operand’s value;
left_result = eval(root.left);
right_result = eval(root.right);
switch (root.datum) {
case + : return left_result + right_result;
case * : return left_result * right_result;
:
:
}
}
Function calls
44

An important application of stacks is normally hidden
from view
A
stack is used to allocate space in the computer’s
memory to the variables belonging to the various
functions of a program

Example: a recursive factorial function
 Has
a parameter n and a return value
 As fact calls itself recursively, different calls with
different parameter are active at the same time
 A frame for each call is created and place on TOS
 When a given call return, its frame gets popped off
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = factorial(2) * 3;
else
fact = 1;
return fact;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = factorial(2) * 3;
else
fact = 1;
return fact;
}
public static int factorial(int 2)
{
int fact;
if (n > 1)
fact = factorial(1) * 2;
else
fact = 1;
return fact;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = factorial(2) * 3;
else
fact = 1;
return fact;
}
public static int factorial(int 2)
{
int fact;
if (n > 1)
fact = factorial(1) * 2;
else
fact = 1;
return fact;
}
public static int factorial(int 1)
{
int fact;
if (n > 1)
fact = factorial(n - 1) * n;
else
fact = 1;
return fact;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = factorial(2) * 3;
else
fact = 1;
return fact;
}
public static int factorial(int 2)
{
int fact;
if (n > 1)
fact = factorial(1) * 2;
else
fact = 1;
return fact;
}
public static int factorial(int 1)
{
int fact;
if (n > 1)
fact = factorial(n - 1) * n;
else
fact = 1;
return 1;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = factorial(2) * 3;
else
fact = 1;
return fact;
}
public static int factorial(int 2)
{
int fact;
if (n > 1)
fact = 1 * 2;
else
fact = 1;
return fact;
}
public static int factorial(int 1)
{
int fact;
if (n > 1)
fact = factorial(n - 1) * n;
else
fact = 1;
return 1;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = factorial(2) * 3;
else
fact = 1;
return fact;
}
public static int factorial(int 2)
{
int fact;
if (n > 1)
fact = 1 * 2;
else
fact = 1;
return 2;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = 2 * 3;
else
fact = 1;
return fact;
}
public static int factorial(int 2)
{
int fact;
if (n > 1)
fact = 1 * 2;
else
fact = 1;
return 2;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = 2 * 3;
else
fact = 1;
return 6;
}
Download