Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Stacks Outline and Reading The Stack ADT (§4.2. 1) Applications of Stacks (§4.2.1) Array-based implementation (§4.2.2) List-based implementation (§4.4.2) Stacks and Queues 2 The Stack ADT The Stack ADT stores arbitrary objects Insertions and deletions follow the last-in first-out scheme (LIFO) Think of a spring-loaded plate dispenser Stacks and Queues 3 The Stack ADT 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 - sometimes called peek() integer size(): returns the number of elements stored boolean isEmpty(): indicates whether no elements are stored Stacks and Queues 4 Stack errors Overflow Trying to push onto full stack Only a problem with stacks of fixed capacity Underflow Trying to pop from empty stack In Java these should throw exceptions Stacks and Queues 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 Stacks and Queues 6 Example - matching parentheses Brackets are used for grouping and/or priority in many human and computer languages In any language, brackets must be matched Algorithm for checking using a stack Scan text left-to-right Push open brackets, pop for closed brackets At end, stack must be empty Stacks and Queues 7 Example - matching parentheses A*[(B+C)/D+E] Input Op Stack [ push[ [ ( push( [ ) pop [ ] pop Stack is empty at the end of the expression ( Stacks and Queues Brackets are matched 8 Example - matching parentheses A*[(B+C/D+E] Input Op Stack [ push[ [ ( push( [ ] pop [ ( Stacks and Queues Stack is NOT empty at the end of the expression Brackets are NOT matched 9 Example - matching parentheses Notes: A simple change to this algorithm could also check for bracket type Code must take into account possible errors, such as too many closed brackets Stacks and Queues 10 Function (Method) Stack The execution run-time (e.g. JVM Java) keeps track of the chain of active methods with a stack When a method is called, a frame is pushed onto the stack, 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 Stacks and Queues main() { int i = 5; foo(i); } foo(int j) { int k; k = j+1; bar(k); } bar(int m) { … } bar PC = 115 m=6 foo PC = 301 j=5 k=6 main PC = 205 i=5 11 Function Stack - recursion How can a function call itself? int factorial(int n) if n<=1 return 1 else temp= factorial(n-1) return n*temp Stacks and Queues 12 Function Stack - recursion Each invocation has its own set of variables Note the importance of the termination condition!! factorial n=1 tmp=0 int factorial(int n) if n<=1 return 1 factorial n=2 tmp=0 factorial n=2 tmp=0 factorial n=2 tmp=1 factorial n=3 tmp=0 factorial n=3 tmp=0 factorial n=3 tmp=0 factorial n=3 tmp=0 temp= factorial(n-1) factorial n=3 return n*temp tmp=2 factorial n=4 tmp=0 factorial n=4 tmp=0 factorial n=4 tmp=0 factorial n=4 tmp=0 factorial n=4 tmp=0 Stacks and Queues else factorial n=4 tmp=6 13 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 t←t−1 return S[t + 1] … S 0 1 2 t Stacks and Queues 14 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 t←t+1 Limitation of the arrayS[t] ← o based implementation Not intrinsic to the Stack ADT … S 0 1 2 t Stacks and Queues 15 Array-based Stack (cont.) Java note: Out of bounds array indexing generates exception Exceptions are exceptional Do not compromise efficiency in the normal case! Algorithm pop() if isEmpty() then throw EmptyStackException else t←t−1 return S[t + 1] Algorithm pop() try t←t−1 return S[t + 1] catch ArrayIndexOutOfBoundsException t←t+1 throw EmptyStackException Stacks and Queues 16 Performance and Limitations Performance Let n be the number of elements in the stack The space used is N - size of array 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 and Queues 17 List-based Stack Two variables needed - top and size Top of stack could be first or last element top head Newest element becomes new head, so push and pop are O(1) top head Stacks and Queues Newest element becomes new tail, so push and pop are O(n) 18 Exercise - reverse an array using a stack public Integer[ ] reverse(Integer[ ] A) { Stack S = new Stack(A.length); Integer[ ] B = new Integer[A.length]; for (int i=0; i<A.length; i++) S.push(A[i]); for (int i=0; i<A.length; i++) B[i] = (Integer) (S.pop()); return B;} Stacks and Queues A S B 2 7 1 1 0 5 7 1 5 52 11 70 19 Computing Spans 7 We show how to use a stack 6 as an auxiliary data structure 5 in an algorithm Given an an array X, the span 4 S[i] of X[i] is the maximum 3 number of consecutive 2 elements X[j] immediately preceding X[i] and such that 1 X[j] ≤ X[i] 0 Spans have applications to financial analysis E.g., stock at 52-week high Stacks and Queues 0 X S 1 6 1 3 1 2 3 4 2 5 3 4 2 1 20 Naïve Algorithm Algorithm spans1 for each element in input iterate back until bigger element is found save count Stacks and Queues 21 Naïve Algorithm - Quadratic 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 s←1 while s ≤ i ∧ X[i − s] ≤ X[i] s←s+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 Stacks and Queues 22 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 i onto the stack 7 6 5 4 3 2 1 0 Stacks and Queues 0 1 2 3 4 5 6 7 23 Linear Algorithm Each index of the array Algorithm spans2(X, n) S ← new array of n integers A ← new empty stack Is pushed into the stack exactly once for i ← 0 to n − 1 do Is popped from the while (¬A.isEmpty() ∧ stack at most once X[top()] ≤ X[i] ) do The statements in the j ← A.pop() while-loop are if A.isEmpty() then executed at most n S[i] ← i + 1 times else S[i] ← i − j Algorithm spans2 runs A.push(i) in O(n) time return S Stacks and Queues # n 1 n n n n n n n 1 24 Queues Outline and Reading The Queue ADT (§4.3.1) Array-based implementation (§4.3.2) List-based implementation (§4.4.3) Stacks and Queues 26 The Queue ADT The Queue ADT stores arbitrary objects Insertions and deletions follow the first-in first-out scheme (FIFO) 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 Stacks and Queues 27 The Queue ADT 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 Stacks and Queues 28 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 Stacks and Queues 29 Array-based Queue - naïve array[0] is front of the queue Expensive - on every dequeue, all remaining elements must be moved - Θ(n) run time dequeue 0 1 2 . . . front rear 0 1 2 . . . front rear Stacks and Queues 0 1 2 . . . front rear 30 Array-based Queue - wrap around 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 normal configuration Q 0 1 2 f r wrapped-around configuration Q 0 1 2 r f Stacks and Queues 31 Array-based Queue - Issues Q r 0 1 2 f Q r=f 0 1 2 f=r - empty or full? Q 0 1 2 r=f Solution: limit queue size to N-1 So f=r only when queue is empty Stacks and Queues 32 Array-based Queue - Issues f<r - size=r-f Q 0 1 2 f r Q 0 1 2 r f f>r - size=? Size = (r+N-f) mod N if r>f N has no effect r<f means there is an N in between Q +N f Stacks and Queues r+N 33 Queue Operations We use the modulo operator (remainder of division) Algorithm size() return (r + N − f) mod N Algorithm isEmpty() return (f = r) Q 0 1 2 f 0 1 2 r r Q f Stacks and Queues 34 Queue Operations (cont.) Operation enqueue throws an exception if the array is full This exception is implementation-dependent 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 f Stacks and Queues 35 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 f Stacks and Queues 36 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; } Stacks and Queues 37 Double-Ended Queues Outline and Reading The Deque ADT (§4.5.1) List-based implementation (§4.5.2) Stacks and Queues 39 The Double-Ended Queue ADT Queue-like ADT Insertions and deletions at both front and rear Pronounced “deck” to avoid confusion Stacks and Queues 40 The Deque ADT Operations Fundamental methods: insertFirst(e) insertLast(e) removeFirst() removeLast() Supporting methods: Stacks and Queues size() isEmpty() first() last() 41 List-based Deque Singly Linked List Implementation Inefficient - removal at rear takes Θ(n) time Doubly Linked List Implementation Each node has a “prev” and “next” link, so all operations run in O(1) time head tail nodes/positions elements Stacks and Queues 42 List-based Deque Sentinel Nodes (Header and Trailer) Simplify adding and removing nodes head tail nodes/positions trailer header elements Stacks and Queues 43 insertFirst without sentinels if head=null newNode <- new Node(obj, null, null) head <- newNode; tail <- newNode; else newNode <- new Node(obj, null, head) head.setPrev(newNode) head <- newNode size++ “else” case head Before insertion newNode Stacks and Queues Special case for first node head After insertion 44 insertFirst without sentinels DLLNode second <- header.getNext() DLLNode newNode <- new DLLNode(obj, header, second) header.setNext(newNode) Works fine even if DLL is empty! second.setPrev(newNode) size++ header A trailer header N header header trailer A newNode second = trailer N trailer Before insertion newNode Stacks and Queues After insertion 45 Performance Run time All methods run in constant time Space Usage O(n) Note Nodes are large Two references to update for operations Stacks and Queues 46 Inplementing stacks and queues Both are easy to implement Code reuse Stack Deque Queue Deque size() isEmpty() top() push(e) pop() size() isEmpty() last() insertLast(e) removeLast() size() isEmpty() front() enqueue(e) dequeue() size() isEmpty() first() insertLast(e) removeFirst() Stacks and Queues 47