ch03 Stacks
ch03 Stacks
Stacks
Chapter Objectives
To learn about the stack data type and how to use its four methods:
push
pop
peek
empty
0 1 2 3 4 5 6 7 8 9 10
( ( w * [ x + y ] / z )
balanced : true
index : 0
Balanced Parentheses (cont.)
Expression: (w * [x + y] / z)
0 1 2 3 4 5 6 7 8 9 10
( ( w * [ x + y ] / z )
balanced : true
index : 1
Balanced Parentheses (cont.)
Expression: (w * [x + y] / z)
0 1 2 3 4 5 6 7 8 9 10
( ( w * [ x + y ] / z )
balanced : true
index : 2
Balanced Parentheses (cont.)
Expression: (w * [x + y] / z)
0 1 2 3 4 5 6 7 8 9 10
(
[ ( w * [ x + y ] / z )
(
balanced : true
index : 3
Balanced Parentheses (cont.)
Expression: (w * [x + y] / z)
0 1 2 3 4 5 6 7 8 9 10
[ ( w * [ x + y ] / z )
(
balanced : true
index : 4
Balanced Parentheses (cont.)
Expression: (w * [x + y] / z)
0 1 2 3 4 5 6 7 8 9 10
[ ( w * [ x + y ] / z )
(
balanced : true
index : 5
Balanced Parentheses (cont.)
Expression: (w * [x + y] / z)
0 1 2 3 4 5 6 7 8 9 10
[ ( w * [ x + y ] / z )
(
balanced : true
index : 6
Balanced Parentheses (cont.)
Expression: (w * [x + y] / z)
0 1 2 3 4 5 6 7 8 9 10
(
[ ( w * [ x + y ] / z )
(
Matches!
Balanced still true
balanced : true
index : 7
Balanced Parentheses (cont.)
Expression: (w * [x + y] / z)
0 1 2 3 4 5 6 7 8 9 10
( ( w * [ x + y ] / z )
balanced : true
index : 8
Balanced Parentheses (cont.)
Expression: (w * [x + y] / z)
0 1 2 3 4 5 6 7 8 9 10
( ( w * [ x + y ] / z )
balanced : true
index : 9
Balanced Parentheses (cont.)
Expression: (w * [x + y] / z)
0 1 2 3 4 5 6 7 8 9 10
( ( w * [ x + y ] / z )
Matches!
Balanced still true
balanced : true
index : 10
Balanced Parentheses (cont.)
public static boolean isBalanced(String expression) { private static final String OPEN = "([{";
// Create an empty stack.
Stack<Character> s = new Stack<Character>(); private static final String CLOSE = ")]}";
boolean balanced = true;
try { private static boolean isOpen(char ch) {
int index = 0; return OPEN.indexOf(ch) > -1;
while (balanced && index < expression.length()) { }
char nextCh = expression.charAt(index);
if (isOpen(nextCh)) { private static boolean isClose(char ch) {
s.push(nextCh); return CLOSE.indexOf(ch) > -1;
} else if (isClose(nextCh)) { }
char topCh = s.pop();
balanced =
OPEN.indexOf(topCh) == CLOSE.indexOf(nextCh);
}
index++;
}
} catch (EmptyStackException ex) {
balanced = false;
}
return (balanced && s.empty());
}
Testing
Provide a variety of input expressions displaying the result
true or false
Try several levels of nested parentheses
Try nested parentheses where corresponding parentheses
are not of the same type
Try unbalanced parentheses
No parentheses at all!
A class which adapts methods of another class by giving different names to essentially
the same methods (push instead of add) is called an adapter class
Writing methods in this way is called method delegation
Implementing a Stack with a List
38
Component (cont.)
public class ListStack<E> implements StackInt<E> {
private List<E> theData;
public ListStack() {
theData = new ArrayList<E>();
}
@Override
public E push(E obj) {
theData.add(obj);
return obj;
}
@Override
public E peek() {
if (empty()) {
throw new EmptyStackException();
}
return theData.get(theData.size() - 1);
}
. . . .
Implementing a Stack with a List
39
Component (cont.)
public class ListStack<E> implements StackInt<E> {
private List<E> theData;
. . . .
@Override
public E pop() {
if (empty()) {
throw new EmptyStackException();
}
return theData.remove(theData.size() - 1);
}
@Override
public boolean empty() {
return theData.size() == 0;
}
}
Implementing a Stack Using an
Array
If we implement a stack as an array,
we would need . . . Allocate storage for an
array with a default
capacity
public class ArrayStack<E> implements StackInt<E> {
private E[] theData;
int topOfStack = -1;
private static final int INITIAL_CAPACITY = 10; Keep track of the top of the
stack (subscript of the
element at the top of the
@SupressWarnings("unchecked") stack; for empty stack = -1)
public ArrayStack() {
theData = (E[])new Object[INITIAL_CAPACITY];
}
There is no size variable or method
Implementing a Stack Using an Array
(cont.)
Character
Object[]
value = 'J'
ArrayStack [0] = null
[1] = null
[2] = null Character
theData =
[3] = null
topOfStack = -1 302
1
[4] = null value = 'a'
[5] = null
[6] = null
[7] = null Character
[8] = null
public E push(E obj) { [9] = null
if (topOfStack == theData.length - 1){ value = 'v'
reallocate();
}
topOfStack++; Character
theData[topOfStack] = obj;
return obj; value = 'a'
}
Implementing a Stack Using an
Array (cont.)
@Override
public E pop() {
if (empty()) {
throw new EmptyStackException();
}
return theData[topOfStack--];
}
Implementing a Stack as a Linked
Data Structure
We can also implement a stack using a linked list of nodes
push
It is easiest
inserts to
a node
insertatand
the
when the list is empty,
delete
head andfrom
popthedeletes
head of thea
pop returns null
node atlist
the head
Implementing a Stack as a Linked
45
Data Structure (cont.)
import java.util.NoSuchElementException;
4 7 * 20 -
4
4 7 * 20 -
7
4
1. create an empty stack of integers
2. while there are more tokens
3. get the next token
4. if the first character of the token is a digit
5. push the token on the stack
6. else if the token is an operator
7. pop the right operand off the stack
8. pop the left operand off the stack
9. evaluate the operation
10. push the result onto the stack
11. pop the stack and return the result
Evaluating Postfix Expressions
(cont.)
4 * 7 4 7 * 20 -
7
4
1. create an empty stack of integers
2. while there are more tokens
3. get the next token
4. if the first character of the token is a digit
5. push the token on the stack
6. else if the token is an operator
7. pop the right operand off the stack
8. pop the left operand off the stack
9. evaluate the operation
10. push the result onto the stack
11. pop the stack and return the result
Evaluating Postfix Expressions
(cont.)
28 4 7 * 20 -
28
4 7 * 20 -
20
28
1. create an empty stack of integers
2. while there are more tokens
3. get the next token
4. if the first character of the token is a digit
5. push the token on the stack
6. else if the token is an operator
7. pop the right operand off the stack
8. pop the left operand off the stack
9. evaluate the operation
10. push the result onto the stack
11. pop the stack and return the result
Evaluating Postfix Expressions
(cont.)
28 - 20 4 7 * 20 -
20
28
1. create an empty stack of integers
2. while there are more tokens
3. get the next token
4. if the first character of the token is a digit
5. push the token on the stack
6. else if the token is an operator
7. pop the right operand off the stack
8. pop the left operand off the stack
9. evaluate the operation
10. push the result onto the stack
11. pop the stack and return the result
Evaluating Postfix Expressions
(cont.)
8 4 7 * 20 -
8
4 7 * 20 -
8