180 likes | 195 Views
Learn about Array-based and Growable Array-based Stack ADT in Java. Explore handling exceptions, performance, and how to implement stack operations.
E N D
Outline and Reading • The Stack ADT (§2.1.1) • Array-based implementation (§2.1.1) • Growable array-based stack (§1.5) • Java.util.Stack class • Java.util.Vector • Applications for Stack Stacks
Abstract Data Types (ADTs) • An abstract data type (ADT) is an abstraction of a data structure • An ADT specifies: • Data stored • Operations on the data • Error conditions associated with operations • Example: ADT modeling a simple stock trading system • The data stored are buy/sell orders • The operations supported are • order buy(stock, shares, price) • order sell(stock, shares, price) • void cancel(order) • Error conditions: • Buy/sell a nonexistent stock • Cancel a nonexistent order Stacks
The Stack ADT • The Stack ADT stores arbitrary objects • Stack follows Last In First Out (LIFO) discipline. That is, insertions and deletions follow the last-in first-out scheme • Think of a spring-loaded plate dispenser • Main stack operations: • push(object): inserts an element • object pop(): removes and returns the last inserted element • Auxiliary stack operations: • object top(): returns the last inserted element without removing it • integer size(): returns the number of elements stored • boolean isEmpty(): indicates whether no elements are stored Stacks
Handling Exceptions/Error Conditions • Attempting the execution of an operation of ADT may sometimes cause an error condition, called an exception • Exceptions are said to be “thrown” by an operation that cannot be executed • In the Stack ADT, operations pop and top cannot be performed if the stack is empty • Attempting the execution of pop or top on an empty stack throws an EmptyStackException • We will look into Java exception handling in the next week. Stacks
Applications of Stacks • Page-visited history in a Web browser • Undo sequence in a text editor • Every process in computer system has a user stack to maintain its context. • The subroutine/method call structure is maintained in a LIFO basis. • Auxiliary data structure for algorithms Stacks
A simple way of implementing the Stack ADT uses an array We add elements from left to right A variable keeps track of the index of the top element Array-based Stack Algorithmsize() returnt +1 Algorithmpop() ifisEmpty()then throw EmptyStackException else tt 1 returnS[t +1] … S 0 1 2 t Stacks
… S 0 1 2 t Array-based Stack (cont.) • The array storing the stack elements may become full • A push operation will then throw a FullStackException • Limitation of the array-based implementation • Not intrinsic to the Stack ADT Algorithmpush(o) ift=S.length 1then throw FullStackException else tt +1 S[t] o Stacks
Performance and Limitations • Performance • Let n be the number of elements in the stack • The space used is O(n) • Each operation runs in time O(1) • Limitations • The maximum size of the stack must be defined a priori and cannot be changed • Trying to push a new element into a full stack causes an implementation-specific exception Stacks
Growable Array-based Stack Algorithmpush(o) ift=S.length 1then A new array of size … fori0tot do A[i] S[i] S A tt +1 S[t] o • In a push operation, when the array is full, instead of throwing an exception, we can replace the array with a larger one • How large should the new array be? • incremental strategy: increase the size by a constant c; O(n) for push operations • doubling strategy: double the size; O(1) for push operation Stacks
Stack Interface in Java public interfaceStackInterface{ public int size(); public boolean empty(); public Object top()throwsEmptyStackException; public voidpush(Object o); public Object pop()throwsEmptyStackException;} • Java interface corresponding to our Stack ADT • Requires the definition of class EmptyStackException • Different from the built-in Java class java.util.Stack • We will look at exceptions later. Stacks
Array-based Stack in Java public class ArrayStack implements StackInterface { private Object[] _items; private int top = -1; private int capacity = 20; public ArrayStack () { _items = new Object[capacity]; } Stacks
Push and other methods public int size() { return top +1;} public boolean isEmpty() { return (top < 0);} public void push(Object obj) { if (top == _items.length -1) { // ASSERT: stack capacity full Object[] tmp = new Object[2*length]; for (int i= 0; i< _items.length; i++) tmp [i] = _items[i]; _items = tmp; top++; capacity = capacity*2; _items[top] = obj; } Stacks
Pop and top method public Object top() { if (empty() ) { System.out.println(“empty”); return null; } else return _items[top]); } public Object pop() { if (empty() ) { System.out.println(“empty”); return null; } else { Object elem = _items[top]); top = top –1; } return elem; } } Stacks
Stack Class Hierarchy AbstractList extends Vector List, Cloneable, Serializable java.util.Vector implements extends Java.util.Stack Stack Stacks
Stack Class Diagram Stack //constructor Stack() //methods Object push(Object item) Object pop() Object peek() int search(Object o) //predicate method boolean empty() Stacks
java.util.Vector Vector Vector() // constructor boolean addElement(Object obj); // add to the end Object elementAt(int index); //return element at index, accessor int size(); boolean isEmpty() Object remove (int index); // remove element at index: mutator Object lastElement(); // accessor String toString(); Object[] toArray(); //other methods Stacks
Java.util.Stack Lets see how easy it is to reuse java.util.Vector to implement a Stack Stacks