This week COSC 1030.03 Week 9, March 8, 2004 Read chapter 19 Work on assignment #3 Discussed in Tutorial this week Must have a partial solution shown to your TA next week. Data structures (continued) S tacks, Queues, Lists, S ets, Lecture7 notes are used for both weeks 7 and 8 (no additional notes for week 8). Abstract Data Type (ADT) Abstract Data Type (ADT): a mode l of a set of data together with operations allowed on them. Hence it defines a type. abstract implies the model specifies what needs to be done rather than how it should be done (devoid of any implementation details) J ava allows you to define your own types List ADT Allows the following operations add(object): add to the end of the list remove(index): remove the one at index size(): get the size of the list get(index): get the object at index etc. However, it does not specify how these operations are carried out Lis t ADT Implementations Data Struc tures and Algorithms List ADT with two implementations Array 0 1 2 3 head 0 1 2 3 φ A data structure provides means of organizing data examples: array, linked list, tree (hierarchical) An algorithm provides a clear, step by step, instructions for solving a problem. The terms data structure and ADT have been used interchangeably Linked structure 1
Historical Notes S tructured programming (1970s): emphasis on the use of procedures emphasis on top-down design reflected in Pascal, C, Modular-2 Object-oriented programming(1980s): emphasis on abstract data types ability to change implementation of an ADT emphasis on bottom-up design reflected in J ava, C++, Eiffel, S malltalk Other ADTs ADT S tack: linear structure (LIFO) Queue: linear structure (FIFO) Tree: hierarchical Stack ADT The S tack ADT stores arbitrary objects Insertions, deletions follow the last-in-first-out Think of a spring-loaded plate dispenser S tack operations: push(object): inserts an element object pop(): removes and returns the last inserted element object top(): returns the last inserted element without removing it integer size(): returns the number of elements stored boolean isempty(): indicates whether stack is empty Applications of Stack Direct applications Page-visited history in a Web browser Undo sequence in a text editor Chain of method calls in the J ava Virtual Machine Indirect applications Auxiliary data structure for algorithms Component of other data structures Stack in J VM From Data Structures and Algorithms in J ava by Goodrich and Tamassia Stac k Implementation The J ava Virtual Machine (J VM) keeps track of the chain of active methods with a stack When a method is called, the J VM pushes on the stack a frame containing Local variables and return value Program counter, keeping track of the statement being executed When a method ends, its frame is popped from the stack and control is passed to the method on top of the stack main() { int i = 5; foo(i); foo(int j) { int k; k = j+1; bar(k); bar(int m) { S implification of a linked list Add/remove at one end of the list Covered in previous lectures Implementation using an array S tart with a maximum size 2
public class ArrayStack { private Object[] elems; private int sp; private static final int MAXSIZE = 100; public ArrayStack() { elems = new Object[MAXSIZE]; sp = 0; public void push(object o) { if(sp >= MAXSIZE) throw new RuntimeException("ArrayStack stack overflow"); elems[sp] = o; sp++; public boolean isempty() { return sp == 0; public Object pop() { if(sp <= 0) throw new RuntimeException("ArrayStack stack underflow"); sp--; return elems[sp]; 4 3 2 2 1 0 sp Array-bas ed Stac k Very efficient O(1) push, pop, isempty() Requires a predefined MaxS ize We have two options if stack becomes full: throw an exception increase the size of the array We have explored both options How to implement top using.. How to copy a stack Top operation implementation using other stack operations? peek at the top element public Object top() { Object o = pop(); push(o); return o; Copy a stack to a new stack? public ArrayStack copy() { ArrayStack st = new ArrayStack(); while(!this.isempty()) { Object o = this.pop(); st.push(o); AttaryStack st2 = new ArrayStack(); while(!st.empty()) { Object o = st.pop(); this.push(o); st2.push(o); return st2; A B C D E E D C B A A B C D E this st st2 Stack in J ava Library J ava Stack public class Stac k extends Vector The Stack class represents a last-in-first-out (LIFO) stack of objects. It extends class Vector with five operations that allow a vector to be treated as a stack. The usual push and pop operations are provided, as well as a method to peek at the top item on the stack, a method to test for whether the stack is empty, and a method to search the stack for an item and discover how far it is from the top. When a stack is first created, it contains no items. boolean empty() Tests if this stack is empty. Object peek() Looks at the object at the top of this stack without removing it from the stack. Object pop() Removes the object at the top of this stack and returns that object as the value of this function. Object push(object item) Pushes an item onto the top of this stack. int search(object o) Returns the 1-based position where an object is on this stack. 3
Evaluating Pos tfix Expres s ion Algebraic expressions in infix notation: (4 + 5*(6-2)) Parenthesis are used to group subexpressions Postfix notation can be used to specify an expression without parenthesis 4 5 6 2 - * + Pos tfix Notation Postfix expression Infix expression A B + (A + B) ABC+* (A*(B+ C)) XYZ+- AB*/ (X - (Y + Z))/(A*B) M2^N3^-AB+* (M^2 - N^2)*(A + B) ^ represents exponentiation operator Algorithm for Evaluating a Postfix expression Create a new stack s tokens = tokenize the input string while (more tokens left){ o = next token; if o is an operand then s.push(o) else a2 = s.pop(); a1 = s.pop(); a3 = evaluate a1 o a2 s.push(a3) Evaluating Pos tfix Expres s ion public static void main(string[] args){ S tring x = "5 2 /"; S ystem.out.println(x + " = " + evalpostfix(x)); x = "5 2 ^ 3 2 ^ - 5 3 - *"; S ystem.out.println(x + " = " + evalpostfix(x)); Output 5 2 /= 2.5 5 2 ^ 3 2 ^ - 5 3 - * = 32.0 Evaluation Pos tfix Expres s ion Output lines in reverse order static double evalpostfix(string in){ static double eval(string a1, String a2, S tring final S tring op = "+-/*^"; op) StringTokenizer tokens = new { S tringtokenizer(in); double a1val = Double.parseDouble(a1); S tack s = new S tack(); double a2val = Double.parseDouble(a2); while(tokens.hasmoretokens()){ switch(op.charat(0)){ String t = tokens.nexttoken(); case '+': return a1val + a2val; if (op.indexof(t) == -1) case '-': return a1val - a2val; s.push(t); case '*': return a1val * a2val; else { case '/': return a1val /a2val; String a2 = (String) s.pop(); case '^': return Math.pow(a1Val, String a1 = (String) s.pop(); a2val); s.push("" + eval(a1, a2, t)); return 0; return(double.parsedouble((s tring) s.pop())); Read a file, line by line, and output the lines in the order opposite to input order, using a stack File contains: to have and to hold Output: to hold and to have static void reverse(string file){ S tack s = new S tack(); UniReader ur = new UniReader(file); S tring line = ur.readline(); while (!ur.eof()){ s.push(line); line = ur.readline(); while (s.size() > 0) IO.println((S tring) s.pop()); ur.close(); 4
Queue ADT The Queue ADT stores arbitrary objects Insertions and deletions follow the first-in first-out Insertions are at the rear of the queue and removals are at the front of the queue queue operations: enqueue(object): inserts an element at the end of the queue object dequeue(): removes and returns the element at the front of the queue object front(): returns the element at the front without removing it integer size(): returns the number of elements stored boolean isempty(): indicates whether no elements are stored Queue Applic ations Direct applications Waiting lists, bureaucracy Access to shared resources (e.g., printer) Multiprogramming Indirect applications Auxiliary data structure for algorithms Component of other data structures Simulation Queue Implementations We have already seen this in the Hair S alon S imulation: Linked list enqueue, dequeue Events occur (people arrive) with probability p Add them to a queue front φ If able to do more work Take person from the head of the queue, and process them front φ enqueue front φ dequeue Queue Implementations J ava Queue Linked list Done previously Using an array Quite subtle Add to the end and remove from front What happens when array is filled? Idea of circular arrays back 0 1 2 3 front 0 1 2 3 front back Use LinkedList public class LinkedList extends AbstractSequentialList implements List, Cloneable, Serializable Linked list implementation of the List interface. Implements all optional list operations, and permits all elements (including null). In addition to implementing the List interface, the LinkedList class provides uniformly named methods to get, remove and insert an element at the beginning and end of the list. These operations allow linked lists to be used as a stack, queue, or double-ended queue (deque). 5
List Create, add, remove, index(), ArrayLists, LinkeLists Done in lecture earlier Great for holding a list of multiple, (different) things Like DVD s, etc. Inefficient, so not great for large N Doing things with Lists Lists are very general purpose, Large API S ize(), search functions, use of equals() Reasonably inefficient Great for small n problems though Set Create, add(), contains(), remove(), Like lists but do not contain duplicates. Add(o) fails if contains(o) is true Useful for maintaining state information Flags J ava does not support ArrayS et or LinkedS et S upport HashS et, LinkedHashS et How J ava implements Collec tions Interface java.util.collection Add(), clear(), isempty(), size(),. All classes that implement the collection must define all of these methods But can throw java.lang.unsupportedoperationexception Subclass of J ava.lang.exception java.util.abs trac tcollec tion and java.util.abs trac tsequentiallis t Abstract classes that implements the Collection interface One designed for things that have eventually implementations based on random access One designed for things based on linked lists AbstractCollection public abstract class AbstractCollection extends Object implements Collection This class provides a skeletal implementation of the Collection interface, to minimize the effort required to implement this interface. Direct Known Subclasses: AbstractList, AbstractS et 6
AbstractS equentiallist AbstractList subclasses public abstract class AbstractSequentialList extends AbstractList This class provides a skeletal implementation of the List interface to minimize the effort required to implement this interface backed by a "sequential access" data store (such as a linked list). For random access data (such as an array), AbstractList should be used in preference to this class. This class is the opposite of the AbstractList class in the sense that it implements the "random access" methods (get(int index), set(int index, Object element), set(int index, Object element), add(int index, Object element) and remove(int index)) on top of the list's list iterator, instead of the other way around. ArrayList An extendable array Vector Like ArrayList but The underlying array can shrink (as well as grow) J ava.util.stack is a subclass of Vector Direct Known Subclasses: LinkedList Abs trac tsequentiallis t public interface iterator { J ava.util.linkedlist Implements the entire collection interface addfirst(), addlast(), removefirst, removelast() Internally is a doubly linked list. A queue is a trivial extension of a linkedlist public boolean hasnext(); //True iff more elements in the iterator public Object next(); //Returns next element in the iteration void remove() throws UnsupportOperationException //Removes last element obtained via next() from the collection. //Optional method - hence may throw exception How do you implement an Iterator? How to implement iterator Advanced topic Use inner classes A class can define within it, another class This class can access all of the fields of its outer class. Public MyLinkedList {.. private class MyListIterator implements Iterator{ protected MyLinkedList list; protected MyNode cur; public ListIterator(MyLinkedList ls){ list = ls; cur = list.head; public boolean hasnext(){ return (cur!= null); public Object next() throws NoSuchElementException{ if (!hasnext() ) throw new NoSuchEelementException(); Object o = cur.geto(); cur = cur.getnext(); return o; public iterator elements() { return new MyListIterator(this); 7
Lis ts aren t everything Major classes of data structures remain. Graph Trees Hash Tables wait until 2nd year Graphs Basic idea: A self-referential data structure with nodes referring to any other node in the structure. Nodes can refer to themselves, other nodes, etc. Trees Basic idea: A self-referrential data structure with 0..n (n=2, typically, but not always) links. For binary (n=2) trees A node can be empty or It has a value and two sons (left, right) which refer to trees. Hash Tables Often have collections in which add/search operations are common, but delete operations (rarely) happen Can we build a data structure that is optimized for add/search, but which are (less) efficient for delete? Basic Idea S uppose we have a collection of keys that we need to keep in a list Few deletes Know (rough) number of items that we will have to deal with (<N) Then we define an efficient function f(key) Maps onto 0..N-1 Ideally maps each key onto a different i Basic Idea 2 Hash function maps keys to buckets Ideally, each key maps to a unique bucket It may not happen => collision Have to resolve collisions Many different possibilities We do one here. Other techniques may work better for you. 8
Has hing S tart with a list keys[i] = null Insertion Given key, compute hash=f(key). S tarting at keys[hash], find first null entry and set keys[i]=key Associate a value with the key Lookup Given key, compute hash=f(key) S tarting at keys[hash], search until either keys[i] = key (found) or keys[i]=null (not found) Other techniques possible (J ava uses one) Deleting Can t set hash[i]=null Breaks other hash functions S o set hash[i]=invalid Basically waste the space Rehas hing When the table gets full (or nearly full) Rehash the data into a larger table Very expensive Avoid when possible Doing things with Has htables If deletes don t happen often, and n is not too large, this is the way to go. Extremely efficient Trades off space (empty space in table) for time. Much work has gone into the design of good hash functions java.util.has htable HashTable ht = new Hashtable(); ht.put( one, new Integer(1)); ht.put( two, new Integer(2)); ht.put( three, new Integer(3)); Integer n = (Integer) ht.get( three ); Collis ions J ava.util.hashtable uses buckets which are searched sequentially Aka a linked list 9
Maps, etc. J ust as J ava has Vector s and ArrayLists Has HashTable s and Map s Worth looking at the API of same Take home message Data structures should be part of your programming toolbox No perfect data structure Different tasks require different structures 1030 has covered a small number of them 2nd year will provide more Read Chapter 19 Summary Work on Assignment #3 Make sure you understand how a linked list works (insertion/deletion in/from different positions) Check the registrar s web site for exam details 10