Sunteți pe pagina 1din 22

1

Stacks
(Application, ADT Interface, Implementation)

Outline and Required Reading:

• Stacks (§ 4.1)
• Sample Case Study (§ 4.5)

COSC 2011, Fall 2003, Section A


Instructor: N. Vlajic
2

Stack ADT

Stack – linear data structure organized according to “last-in/first-out”


(LIFO) principle

! stack items can be inserted and removed only at


one end
! stack items are taken out of the stack in reverse
order of their insertion
! in a stack, only top element is accessible!

C
B
A

Examples – page visited history in a Web browser, undo sequence


in a text editor, etc.
3

Stack ADT: Application (1)

Java Virtual Machine – keeps track of the chain of currently active


(Java Method Invocation) methods by using a stack
• at the top of the stack is the frame of the currently
running method, i.e. method that has control over
the execution
• the remaining elements of the stack are suspended
methods that have invoked another method and are
waiting for its termination

invoked terminated
method method

main() {
Top of Java Stack:
job2: … … job1();
currently running method };
job1: …
job1() {
main: … … job2();
Java Stack };
4

Stack ADT: Application (1) (cont.)

Java VM and Recursion – Java Stack enables recursive programming

! fact(1) is called last, but it fact(1) public int fact(int n) {


if n<=1 return 1;
must (will) be executed first
- all other method calls are …
awaiting for its execution else return n*fact(n-1);
! fact(1) is executed without fact(n-2) }
invoking itself recursively !!!
fact(n-1)

fact(n)

Java Stack

What would happen if for every single value of n the recursive method would invoke itself,
i.e. there was no “terminating” value of n?
5

Stack ADT: Interface

There are many ways to implement Stack, but all should have the same interface:

Fundamental Methods public void push(Object element);


(Transformers) /* insert an element at the top of the stack */

push pop public Object pop();


/* remove the top element from the stack */
/* StackEmptyException if stack is empty */

Supporting Methods public int size();


(Observers) /* return the # of objects in the stack */

public boolean isEmpty();


/* return true if the stack is empty */

public Object peek();


/* get the top item without removing it */
/* StackEmptyException if stack is empty */
6

Stack ADT: Interface

Possible Stack ADT Errors - there are 2 types of stack errors that
can occur:
pop
(1) underflow - trying to pop or peek
at an empty stack
• can occur regardless of the underlying
data structure employed

push
(2) overflow - trying to push onto an
already full stack
• can occur only if the underlying data
structure has a fixed capacity
7

Stack ADT: Implementation

Our goal: Implement Stack ADT!

Possible Implementation Techniques:

Use an Array Use a Linked List


8

Stack ADT: Array-Based Implementation

Array of references!!!
Required private Object S[ ];
Instance Variables /* array used to implement the stack */

public static int CAPACITY;


/* default length of the array used to implement the
S[ ]
stack */

public int capacity;


/* length of the array used to implement the stack
specified by the user */
CAPACITY=8

top=2 2
public static int top;
/* index of the top element of the stack, in the array */
1

Stack bottom is at S[0], and “top” represents the last position used.
9

Stack ADT: Array-Based Implementation (cont.)

public class ArrayStack implements Stack {

public static final int CAPACITY = 1000;


private int capacity;
private Object S[ ];
private int top=-1; Indicates that
stack is empty.
public ArrayStack() {
this(CAPACITY); }

public ArrayStack(int cap) {


capacity = cap;
S = new Object[capacity]; }

pubic int size() {


return (top+1); }

public boolean isEmpty() {


return (top<0); }
cont.
10

Stack ADT: Array-Based Implementation (cont.)

pubic void push(Object obj) throws StackFullException {


if (size() == capacity)
Top element of S throw new StackFulException(“Stack overflow.”);
becomes reference S[++top] = obj; }
to new “obj”.
public Object peek() throws StackEmptyExcpetion {
if (isEmpty())
throw new StackEmptyException(“Stack is empty.”);
return S[top]; }

public Object pop() throws StackEmptyExcpetion {


Object elem;
if (isEmpty())
throw new StackEmptyException(“Stack is empty.”);
elem = S[top];
S[top--] = null; The reference should be set to null, so that the
return elem; } element (object) can be picked up by
} garbage collection !!!
11

Stack ADT: Performance of Array-Based Implement.

Run Time – Good!


Good all methods run in constant O(1) time

Method Time
size O(1)
isEmpty O(1)
top O(1)
push O(1)
pop O(1)

Space Usage – Poor!


Poor O(N), where N – array size, n – current # of
≥n
elements in the stack, N≥

General Note – problems arise if attempting to push (N+1) objects


on the stack
12

Stack ADT: Linked List - Based Implementation

Required private Node top;


Instance Variables /* reference to the top element in the stack */

private int size;


/* current number of elements in the stack */

Assume we have only the reference to the head of a Singly Linked List.
Where to place the top – at the head or the tail of the SLL??
(1) top = head ⇒ run time of insert and delete O(1)
(2) top = last element in SLL ⇒ run time of insert and delete O(n)

top of stack = head of SLL top of stack

direction of
traversing
the SLL
head of SLL
13

Stack ADT: Linked List - Based Implement. (cont.)

public class LinkedStack implements Stack {

private Node top;


private int size;

public LinkedStack() {
top = null;
size=0; }

pubic int size() {


return size; }

public boolean isEmpty() {


if (top == null)
return true;
return false; }

cont.
14

Stack ADT: Linked List - Based Implement. (cont.)

In contrast to array-based implement.


pubic void push(Object elem) { here no exception is needed. Explain!
Node v = new Node();
v.setElement(elem);
v.setNext(top);
top = v;
size++; }

public Object peek() throws StackEmptyExcpetion {


if (isEmpty()) throw new StackEmptyException(“Stack is empty.”);
return top.getElement(); }

public Object pop() throws StackEmptyExcpetion {


if (isEmpty()) throw new StackEmptyException(“Stack is empty.”);
Object temp = top.getElement();
top = top.getNext();
size--;
return temp; }
}
15

Stack ADT: Performance of LL - Based Implement.

Run Time – Good!


Good all methods run in constant O(1) time
(no loops or recursions)

Method Time
size O(1)
isEmpty O(1)
top O(1)
push O(1)
pop O(1)

Space Usage – Good!


Good O(n), n – current # of elements in the stack

General Note – no problems with size/overflow


16

Stack ADT: Array vs. Linked List Implementation

Properties Array Linked List


of Stacks Implementation Implementation

ordered access + +
insertions/removals
at a cursor
- +

frequent resizing - +

implementation
complexity / cost + -

In Linked List implementation:


1) each element must contains reference “next” – more space per element needed
2) for every added/removed element, method setNext()/getNext() must be called
17

Stack ADT: Application (2)

Balanced Parentheses • Bracketing is a feature of many languages, both


natural and artificial.

• Whatever the language, all brackets in a phrase


must be paired: for each left bracket there must
be a later matching right bracket.
• Algorithm for Brackets Checking:
1) scan the characters of a given string from left
to right
2) every time a left-bracket occurs, push it onto
the stack
3) every time a right parenthesis occurs, remove
the corresponding left-bracket from the stack

A*[(B+C)/D+E] A*[(B+C/D+E]
Stack empty at the Stack not empty at
end of expression the end of expression
( ⇓ ( ( ( ⇓
brackets are brackets are
[ [ [ balanced !!! [ [ [ [ not balanced !!!
18

Stack ADT: Application (3)

Computing Spans - given an array X, the span S[i] of X[i] is the max
number of consecutive elements X[j] immediately
≤X[i]
preceding X[i], such that X[j]≤

• spans have application in financial analysis – e.g.


stock at 52-week high

stock
price

1 3 2 2 week
19

Stack ADT: Application (3) (cont.)

“spans1” Algorithm

public void spans1(int[ ] X, int n){



int[ ] S = new int[x.length]; /* array of spans of X */
int s;
for (int i=0; i<n; i++) {
NOTE: s is (re)set to 1 ⇒
in every iteration all
s=1;
elements X[0] to X[i-1] while ((s≤
≤i) && (X[i-s]≤
≤X[i])) { s++; };
are compared to X[i] -
redundant !!! S[i]=s;
}
}

n-1 i-1
X 3 5 9 2 7 6 5 T(n) ≈ ∑ ∑ 1 = 1+ 2 + .. + (n − 1) = O(n 2 )
S 1 2 3 1 2 1 1
i=0 j=0
20

Stack ADT: Application (3) (cont.)

Stack-based “spans2” Algorithm

When going from day i to day 0, we


repeatedly “pop” days with prices
less than or equal to X[i], and then
“push” day i on the stack.

Stack not empty: S[i] = i – A.top() X 6 5 4 9 7 6 8


Stack empty: S[i] = i + 1 S 1 1 1 4 1 1 3

Formula used after all required i 0 1 2 3 4 5 6


“pop”-s have been executed,
and before “push” !!! 2 5
A 1 1 4 4 6
0 0 0 3 3 3 2

Keep in the stack only the indices of the elements


visible when “looking back”.
21

Stack ADT: Application (3) (cont.)

Stack-based “spans2” Algorithm

public void spans2(int[ ] X, int n){



int S = new int[x.length]; /* array of spans of X */
Stack A = new Stack(); /* an empty stack */
for (int i=0; i<n; i++) {
while ( (!A.isEmpty()) && (X[i]≥
≥X[A.top()]) ) {
A.pop();
if (A.isEmpty()) S[i]=i+1;
else S[i] = i-A.top();
A.push(i);
}
}

Every index “i” is pushed into the stack exactly once,


and popped from the stack at most once
⇒ T(n) = O(n)
22

Stack ADT: Questions

Q.1 Describe the output of the following series of stack operations:


push(5), push(3), pop(), push(2), pop(), pop(), pop()

Q.2 Make a sketch of a program that reads a word and then writes it
backwards, using Stack ADT.

Q.3 Describe how you can define a new Stack ADT method that
returns the second item from the top of the stack, without
permanently changing the stack. (If you temporarily change
the stack, then you are required to change it back before the
method ends.)
Your description will be in terms of peek(), pop(), and push().

S-ar putea să vă placă și