* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Document
Survey
Document related concepts
Transcript
Stacks Goodrich, Tamassia Linked Lists 1 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 Goodrich, Tamassia 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 Linked Lists 2 The Stack ADT (§4.2) The Stack ADT stores arbitrary objects 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 Goodrich, Tamassia Linked Lists 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 3 Stack Interface in Java Java interface corresponding to our Stack ADT Requires the definition of class EmptyStackException Different from the built-in Java class java.util.Stack public interface Stack { public int size(); public boolean isEmpty(); public Object top() throws EmptyStackException; public void push(Object o); public Object pop() throws EmptyStackException; } Goodrich, Tamassia Linked Lists 4 Exceptions 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 Goodrich, Tamassia Linked Lists 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 5 Applications of Stacks Direct applications Page-visited history in a Web browser Undo sequence in a text editor Chain of method calls in the Java Virtual Machine Indirect applications Auxiliary data structure for algorithms Component of other data structures Goodrich, Tamassia Linked Lists 6 Method Stack in the JVM The Java Virtual Machine (JVM) keeps track of the chain of active methods with a stack When a method is called, the JVM pushes on the stack a frame containing main() { int i = 5; foo(i); } foo(int j) { int k; Local variables and return value Program counter, keeping track of k = j+1; the statement being executed bar(k); When a method ends, its frame } is popped from the stack and control is passed to the method bar(int m) { on top of the stack … } Allows for recursion Goodrich, Tamassia Linked Lists bar PC = 1 m=6 foo PC = 3 j=5 k=6 main PC = 2 i=5 7 Array-based Stack 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 Algorithm size() return t + 1 Algorithm pop() if isEmpty() then throw EmptyStackException else tt1 return S[t + 1] … S 0 1 2 Goodrich, Tamassia t Linked Lists 8 Array-based Stack (cont.) The array storing the stack elements may become full A push operation will then throw a FullStackException Algorithm push(o) if t = S.length 1 then throw FullStackException else tt+1 Limitation of the arrayS[t] o based implementation Not intrinsic to the Stack ADT … S 0 1 2 Goodrich, Tamassia t Linked Lists 9 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 Goodrich, Tamassia Linked Lists 10 Array-based Stack in Java public class ArrayStack implements Stack { // holds the stack elements private Object S[ ]; // index to top element private int top = -1; // constructor public ArrayStack(int capacity) { S = new Object[capacity]); } Goodrich, Tamassia public Object pop() throws EmptyStackException { if isEmpty() throw new EmptyStackException (“Empty stack: cannot pop”); Object temp = S[top]; // facilitates garbage collection S[top] = null; top = top – 1; return temp; } Linked Lists 11 Parentheses Matching Each “(”, “{”, or “[” must be paired with a matching “)”, “}”, or “[” correct: ( )(( )){([( )])} correct: ((( )(( )){([( )])} incorrect: )(( )){([( )])} incorrect: ({[ ])} incorrect: ( Goodrich, Tamassia Linked Lists 12 Parentheses Matching Algorithm Algorithm ParenMatch(X,n): Input: An array X of n tokens, each of which is either a grouping symbol, a variable, an arithmetic operator, or a number Output: true if and only if all the grouping symbols in X match Let S be an empty stack for i=0 to n-1 do if X[i] is an opening grouping symbol then S.push(X[i]) else if X[i] is a closing grouping symbol then if S.isEmpty() then return false {nothing to match with} if S.pop() does not match the type of X[i] then return false {wrong type} if S.isEmpty() then return true {every symbol matched} else return false {some symbols were never matched} Goodrich, Tamassia Linked Lists 13 HTML Tag Matching For fully-correct HTML, each <name> should pair with a matching </name> <body> <center> <h1> The Little Boat </h1> </center> <p> The storm tossed the little boat like a cheap sneaker in an old washing machine. The three drunken fishermen were used to such treatment, of course, but not the tree salesman, who even as a stowaway now felt that he had overpaid for the voyage. </p> <ol> <li> Will the salesman die? </li> <li> What color is the boat? </li> <li> And what about Naomi? </li> </ol> </body> Goodrich, Tamassia The Little Boat The storm tossed the little boat like a cheap sneaker in an old washing machine. The three drunken fishermen were used to such treatment, of course, but not the tree salesman, who even as a stowaway now felt that he had overpaid for the voyage. 1. Will the salesman die? 2. What color is the boat? 3. And what about Naomi? Linked Lists 14 Tag Matching Algorithm Is similar to parentheses matching: import java.util.StringTokenizer; import datastructures.Stack; import datastructures.NodeStack; import java.io.*; /** Simpli.ed test of matching tags in an HTML document. */ public class HTML { /** Nested class to store simple HTML tags */ public static class Tag { String name; // The name of this tag boolean opening; // Is true i. this is an opening tag public Tag() { // Default constructor name = ""; opening = false; } public Tag(String nm, boolean op) { // Preferred constructor name = nm; opening = op; } } /** Is this an opening tag? */ public boolean isOpening() { return opening; } /** Return the name of this tag */ public String getName() {return name; } /** Test if every opening tag has a matching closing tag. */ public boolean isHTMLMatched(Tag[ ] tag) { Stack S = new NodeStack(); // Stack for matching tags for (int i=0; (i<tag.length) && (tag[i] != null); i++) { if (tag[i].isOpening()) S.push(tag[i].getName()); // opening tag; push its name on the stack else { if (S.isEmpty()) // nothing to match return false; if (!((String) S.pop()).equals(tag[i].getName())) // wrong match return false; } } Goodrich, Tamassia } if (S.isEmpty()) return true; // we matched everything return false; // we have some tags that never were matched Linked Lists 15 Tag Matching Algorithm, cont. public final static int CAPACITY = 1000; // Tag array size upper bound /* Parse an HTML document into an array of html tags */ public Tag[ ] parseHTML(BufferedReader r) throws IOException { String line; // a line of text boolean inTag = false ; // true iff we are in a tag Tag[ ] tag = new Tag[CAPACITY]; // our tag array (initially all null) int count = 0 ; // tag counter while ((line = r.readLine()) != null) { // Create a string tokenizer for HTML tags (use < and > as delimiters) StringTokenizer st = new StringTokenizer(line,"<> \t",true); while (st.hasMoreTokens()) { String token = (String) st.nextToken(); if (token.equals("<")) // opening a new HTML tag inTag = true; else if (token.equals(">")) // ending an HTML tag inTag = false; else if (inTag) { // we have a opening or closing HTML tag if ( (token.length() == 0) | | (token.charAt(0) != ’/’) ) tag[count++] = new Tag(token, true); // opening tag else // ending tag tag[count++] = new Tag(token.substring(1), false); // skip the } // Note: we ignore anything not in an HTML tag } } return tag; // our array of tags } /** Tester method */ public static void main(String[ ] args) throws IOException { BufferedReader stdr; // Standard Input Reader stdr = new BufferedReader(new InputStreamReader(System.in)); HTML tagChecker = new HTML(); if (tagChecker.isHTMLMatched(tagChecker.parseHTML(stdr))) System.out.println("The input file is a matched HTML document."); else System.out.println("The input file is not a matched HTML document."); } } Linked Lists Goodrich, Tamassia 16 Computing Spans (not in book) 7 We show how to use a stack 6 as an auxiliary data structure 5 in an algorithm 4 Given an an array X, the span 3 S[i] of X[i] is the maximum 2 number of consecutive elements X[j] immediately 1 preceding X[i] and such that 0 X[j] X[i] Spans have applications to financial analysis E.g., stock at 52-week high Goodrich, Tamassia Linked Lists 0 X S 1 6 1 3 1 2 3 4 2 5 3 4 2 1 17 Quadratic Algorithm Algorithm spans1(X, n) Input array X of n integers Output array S of spans of X S new array of n integers for i 0 to n 1 do s1 while s i X[i s] X[i] ss+1 S[i] s return S # n n n 1 + 2 + …+ (n 1) 1 + 2 + …+ (n 1) n 1 Algorithm spans1 runs in O(n2) time Goodrich, Tamassia Linked Lists 18 Computing Spans with a Stack We keep in a stack the indices of the elements visible when “looking back” We scan the array from left to right Let i be the current index We pop indices from the stack until we find index j such that X[i] X[j] We set S[i] i j We push x onto the stack Goodrich, Tamassia Linked Lists 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 19 Linear Algorithm Each index of the array Is pushed into the stack exactly one Is popped from the stack at most once The statements in the while-loop are executed at most n times Algorithm spans2 runs in O(n) time Goodrich, Tamassia Algorithm spans2(X, n) # S new array of n integers n A new empty stack 1 for i 0 to n 1 do n while (A.isEmpty() X[A.top()] X[i] ) do n A.pop() n if A.isEmpty() then n S[i] i + 1 n else S[i] i A.top() n A.push(i) n return S 1 Linked Lists 20 Queues Goodrich, Tamassia Linked Lists 21 The Queue ADT (§4.3) The Queue ADT stores arbitrary objects Insertions and deletions follow the first-in first-out scheme Insertions are at the rear of the queue and removals are at the front of the queue Main 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 Goodrich, Tamassia Linked Lists Auxiliary queue operations: 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 Exceptions Attempting the execution of dequeue or front on an empty queue throws an EmptyQueueException 22 Queue Example Operation enqueue(5) enqueue(3) dequeue() enqueue(7) dequeue() front() dequeue() dequeue() isEmpty() enqueue(9) enqueue(7) size() enqueue(3) enqueue(5) dequeue() Goodrich, Tamassia Output – – 5 – 3 7 7 “error” true – – 2 – – 9 Q (5) (5, 3) (3) (3, 7) (7) (7) () () () (9) (9, 7) (9, 7) (9, 7, 3) (9, 7, 3, 5) (7, 3, 5) Linked Lists 23 Applications of Queues 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 Goodrich, Tamassia Linked Lists 24 Array-based Queue Use an array of size N in a circular fashion Two variables keep track of the front and rear f index of the front element r index immediately past the rear element Array location r is kept empty normal configuration Q 0 1 2 f r wrapped-around configuration Q 0 1 2 Goodrich, Tamassia r f Linked Lists 25 Queue Operations We use the modulo operator (remainder of division) Algorithm size() return (N f + r) mod N Algorithm isEmpty() return (f = r) Q 0 1 2 f 0 1 2 r r Q Goodrich, Tamassia f Linked Lists 26 Queue Operations (cont.) Operation enqueue throws an exception if the array is full This exception is implementationdependent Algorithm enqueue(o) if size() = N 1 then throw FullQueueException else Q[r] o r (r + 1) mod N Q 0 1 2 f 0 1 2 r r Q Goodrich, Tamassia f Linked Lists 27 Queue Operations (cont.) Operation dequeue throws an exception if the queue is empty This exception is specified in the queue ADT Algorithm dequeue() if isEmpty() then throw EmptyQueueException else o Q[f] f (f + 1) mod N return o Q 0 1 2 f 0 1 2 r r Q Goodrich, Tamassia f Linked Lists 28 Queue Interface in Java Java interface corresponding to our Queue ADT Requires the definition of class EmptyQueueException No corresponding built-in Java class public interface Queue { public int size(); public boolean isEmpty(); public Object front() throws EmptyQueueException; public void enqueue(Object o); public Object dequeue() throws EmptyQueueException; } Goodrich, Tamassia Linked Lists 29 Application: Round Robin Schedulers We can implement a round robin scheduler using a queue, Q, by repeatedly performing the following steps: 1. 2. 3. e = Q.dequeue() Service element e Q.enqueue(e) The Queue 1. Deque the next element 2 . Service the next element 3. Enqueue the serviced element Shared Service Goodrich, Tamassia Linked Lists 30 Linked Lists Goodrich, Tamassia Linked Lists 31 Singly Linked List (§ 4.4.1) A singly linked list is a concrete data structure consisting of a sequence of nodes Each node stores next element link to the next node node elem A Goodrich, Tamassia B C Linked Lists D 32 The Node Class for List Nodes public class Node { // Instance variables: private Object element; private Node next; /** Creates a node with null references to its element and next node. */ public Node() { this(null, null); } /** Creates a node with the given element and next node. */ public Node(Object e, Node n) { element = e; next = n; } // Accessor methods: public Object getElement() { return element; } public Node getNext() { return next; } // Modifier methods: public void setElement(Object newElem) { element = newElem; } public void setNext(Node newNext) { next = newNext; } } Goodrich, Tamassia Linked Lists 33 Inserting at the Head 1. Allocate a new node 2. Insert new element 3. Have new node point to old head 4. Update head to point to new node Goodrich, Tamassia Linked Lists 34 Removing at the Head 1. Update head to point to next node in the list 2. Allow garbage collector to reclaim the former first node Goodrich, Tamassia Linked Lists 35 Inserting at the Tail 1. Allocate a new 2. 3. 4. 5. node Insert new element Have new node point to null Have old last node point to new node Update tail to point to new node Goodrich, Tamassia Linked Lists 36 Removing at the Tail Removing at the tail of a singly linked list is not efficient! There is no constant-time way to update the tail to point to the previous node Goodrich, Tamassia Linked Lists 37 Stack with a Singly Linked List We can implement a stack with a singly linked list The top element is stored at the first node of the list The space used is O(n) and each operation of the Stack ADT takes O(1) time nodes t elements Goodrich, Tamassia Linked Lists 38 Queue with a Singly Linked List We can implement a queue with a singly linked list The front element is stored at the first node The rear element is stored at the last node The space used is O(n) and each operation of the Queue ADT takes O(1) time r nodes f elements Goodrich, Tamassia Linked Lists 39 Vectors and Array Lists Goodrich, Tamassia Linked Lists 40 The Vector ADT (§5.1) The Vector ADT extends the notion of array by storing a sequence of arbitrary objects An element can be accessed, inserted or removed by specifying its rank (number of elements preceding it) An exception is thrown if an incorrect rank is specified (e.g., a negative rank) Goodrich, Tamassia Main vector operations: object elemAtRank(integer r): returns the element at rank r without removing it object replaceAtRank(integer r, object o): replace the element at rank with o and return the old element insertAtRank(integer r, object o): insert a new element o to have rank r object removeAtRank(integer r): removes and returns the element at rank r Additional operations size() and isEmpty() Linked Lists 41 Applications of Vectors Direct applications Sorted collection of objects (elementary database) Indirect applications Auxiliary data structure for algorithms Component of other data structures Goodrich, Tamassia Linked Lists 42 Array-based Vector Use an array V of size N A variable n keeps track of the size of the vector (number of elements stored) Operation elemAtRank(r) is implemented in O(1) time by returning V[r] V 0 1 2 Goodrich, Tamassia n r Linked Lists 43 Insertion In operation insertAtRank(r, o), we need to make room for the new element by shifting forward the n r elements V[r], …, V[n 1] In the worst case (r = 0), this takes O(n) time V 0 1 2 r n 0 1 2 r n 0 1 2 o r V V Goodrich, Tamassia Linked Lists n 44 Deletion In operation removeAtRank(r), we need to fill the hole left by the removed element by shifting backward the n r 1 elements V[r + 1], …, V[n 1] In the worst case (r = 0), this takes O(n) time V 0 1 2 o r n 0 1 2 r n 0 1 2 r V V Goodrich, Tamassia Linked Lists n 45 Performance In the array based implementation of a Vector The space used by the data structure is O(n) size, isEmpty, elemAtRank and replaceAtRank run in O(1) time insertAtRank and removeAtRank run in O(n) time If we use the array in a circular fashion, insertAtRank(0) and removeAtRank(0) run in O(1) time In an insertAtRank operation, when the array is full, instead of throwing an exception, we can replace the array with a larger one Goodrich, Tamassia Linked Lists 46 Growable Array-based Vector In a push operation, when Algorithm push(o) the array is full, instead of if t = S.length 1 then throwing an exception, we A new array of can replace the array with size … a larger one for i 0 to t do A[i] S[i] How large should the new SA array be? incremental strategy: increase the size by a constant c doubling strategy: double the size Goodrich, Tamassia Linked Lists tt+1 S[t] o 47 Comparison of the Strategies We compare the incremental strategy and the doubling strategy by analyzing the total time T(n) needed to perform a series of n push operations We assume that we start with an empty stack represented by an array of size 1 We call amortized time of a push operation the average time taken by a push over the series of operations, i.e., T(n)/n Goodrich, Tamassia Linked Lists 48 Incremental Strategy Analysis We replace the array k = n/c times The total time T(n) of a series of n push operations is proportional to n + c + 2c + 3c + 4c + … + kc = n + c(1 + 2 + 3 + … + k) = n + ck(k + 1)/2 Since c is a constant, T(n) is O(n + k2), i.e., O(n2) The amortized time of a push operation is O(n) Goodrich, Tamassia Linked Lists 49 Doubling Strategy Analysis We replace the array k = log2 n times The total time T(n) of a series of n push operations is proportional to n + 1 + 2 + 4 + 8 + …+ 2k = n + 2k + 1 1 = 2n 1 T(n) is O(n) The amortized time of a push operation is O(1) Goodrich, Tamassia Linked Lists geometric series 2 4 1 1 8 50 Lists Goodrich, Tamassia Linked Lists 51 Position ADT (§ 5.2.2) The Position ADT models the notion of place within a data structure where a single object is stored It gives a unified view of diverse ways of storing data, such as a cell of an array a node of a linked list Just one method: object element(): returns the element stored at the position Goodrich, Tamassia Linked Lists 52 List ADT (§ 5.2.3) The List ADT models a sequence of positions storing arbitrary objects It establishes a before/after relation between positions Generic methods: Accessor methods: Update methods: size(), isEmpty() Goodrich, Tamassia Linked Lists first(), last() prev(p), next(p) replace(p, e) insertBefore(p, e), insertAfter(p, e), insertFirst(e), insertLast(e) remove(p) 53 Doubly Linked List A doubly linked list provides a natural implementation of the List ADT Nodes implement Position and store: element link to the previous node link to the next node prev next elem node Special trailer and header nodes nodes/positions header trailer elements Goodrich, Tamassia Linked Lists 54 Insertion We visualize operation insertAfter(p, X), which returns position q p A B C p A q B C X p A Goodrich, Tamassia q B Linked Lists X C 55 Insertion Algorithm Algorithm insertAfter(p,e): Create a new node v v.setElement(e) v.setPrev(p) {link v to its predecessor} v.setNext(p.getNext()) {link v to its successor} (p.getNext()).setPrev(v) {link p’s old successor to v} p.setNext(v) {link p to its new successor, v} return v {the position for the element e} Goodrich, Tamassia Linked Lists 56 Deletion We visualize remove(p), where p = last() p A B C A B C D p D A Goodrich, Tamassia B Linked Lists C 57 Deletion Algorithm Algorithm remove(p): t = p.element {a temporary variable to hold the return value} (p.getPrev()).setNext(p.getNext()) {linking out p} (p.getNext()).setPrev(p.getPrev()) p.setPrev(null) {invalidating the position p} p.setNext(null) return t Goodrich, Tamassia Linked Lists 58 Performance In the implementation of the List ADT by means of a doubly linked list The space used by a list with n elements is O(n) The space used by each position of the list is O(1) All the operations of the List ADT run in O(1) time Operation element() of the Position ADT runs in O(1) time Goodrich, Tamassia Linked Lists 59 Sequences and Iterators Goodrich, Tamassia Linked Lists 60 Sequence ADT (§ 5.3) The Sequence ADT is the union of the Vector and List ADTs Elements accessed by List-based methods: Rank, or Position Generic methods: size(), isEmpty() Vector-based methods: elemAtRank(r), replaceAtRank(r, o), insertAtRank(r, o), removeAtRank(r) Goodrich, Tamassia Linked Lists first(), last(), prev(p), next(p), replace(p, o), insertBefore(p, o), insertAfter(p, o), insertFirst(o), insertLast(o), remove(p) Bridge methods: atRank(r), rankOf(p) 61 Applications of Sequences The Sequence ADT is a basic, generalpurpose, data structure for storing an ordered collection of elements Direct applications: Generic replacement for stack, queue, vector, or list small database (e.g., address book) Indirect applications: Building block of more complex data structures Goodrich, Tamassia Linked Lists 62 Linked List Implementation A doubly linked list provides a reasonable implementation of the Sequence ADT Nodes implement Position and store: element link to the previous node link to the next node Position-based methods run in constant time Rank-based methods require searching from header or trailer while keeping track of ranks; hence, run in linear time Special trailer and header nodes nodes/positions header trailer elements Goodrich, Tamassia Linked Lists 63 Array-based Implementation elements We use a circular array storing positions A position object stores: Element Rank Indices f and l keep track of first and last positions 0 1 3 positions S f Goodrich, Tamassia 2 Linked Lists l 64 Sequence Implementations Operation size, isEmpty atRank, rankOf, elemAtRank first, last, prev, next replace replaceAtRank insertAtRank, removeAtRank insertFirst, insertLast insertAfter, insertBefore remove Goodrich, Tamassia Linked Lists Array 1 1 1 1 1 n 1 n n List 1 n 1 1 n n 1 1 1 65 Iterators (§ 5.4) An iterator abstracts the process of scanning through a collection of elements Methods of the ObjectIterator ADT: object object() boolean hasNext() object nextObject() reset() ObjectIterator elements() Two notions of iterator: Extends the concept of Position by adding a traversal capability Implementation with an array or singly linked list Goodrich, Tamassia An iterator is typically associated with an another data structure We can augment the Stack, Queue, Vector, List and Sequence ADTs with method: Linked Lists snapshot: freezes the contents of the data structure at a given time dynamic: follows changes to the data structure 66