CS210- Lecture 4 Jun 7, 2005 Agenda Stacks Array based implementation of Stacks Applications of Stacks Queues 6/30/2016 CS210-Summer 2005, Lecture 4 1 Stacks A Stack is a container of objects that are inserted and removed according to the last-in first-out (LIFO) principle. Objects can be inserted (push) into a stack at any time, but only the most recently inserted objects can be removed (pop) at any time. 6/30/2016 CS210-Summer 2005, Lecture 4 2 Stacks 1. 2 1. Push(2) 2. Push(10) 3. Pop() 10 2. 4. Pop() 2 3. 2 4. 6/30/2016 CS210-Summer 2005, Lecture 4 3 ADT (Abstract Data Type) An Abstract data type is a type in the same sense as int and double, that is there can be variables of the type, and there are operations available for the type that the user (client) don’t see implemented, just trusts to do the job. An ADT has an API that defines the operations allowed on the type, and the implementation of the operations keeps all of its data encapsulated from the client. 6/30/2016 CS210-Summer 2005, Lecture 4 4 Stack ADT Stack ADT supports following methods: push(o): Insert object o at the top of stack Input: Object o Output: None pop(): Remove and return the top object on the stack. Error occurs if the stack is empty. 6/30/2016 Input: None Output: Top object CS210-Summer 2005, Lecture 4 5 Stack ADT size(): Return the number of objects in the stack isEmpty(): Return a boolean indicating if the stack is empty. Input: none Output: Integer (total number of objects) Input: None Output: boolean (true if stack is empty, false otherwise) top(): Return the top object on the stack, without removing it. Error occurs if the stack is empty. Input: None Output: Top object 6/30/2016 CS210-Summer 2005, Lecture 4 6 Stack ADT in Java Stack data structure is included as a “built-in” class in the java.util package of java. Methods: push (Object item) pop() peek() //equivalent of top empty() //equivalent of isEmpty size() 6/30/2016 CS210-Summer 2005, Lecture 4 7 A Simple Array Based Implementation We can implement a stack by storing its elements in an array. The stack in this implementation consists of an N element array S plus an integer variable t that gives the index of the top element in array S. S 0 6/30/2016 1 2 ……………………………… CS210-Summer 2005, Lecture 4 t N -1 8 A Simple Array Based Implementation We initialize t to -1 (which means stack is empty initially). size: No of elements in stack: t + 1. (-1 + 1 = 0 elements initially) isEmpty: if t < 0 then true otherwise false. To push object: If size is N (full stack) throw Exception Otherwise increment t and store new object at S[t] 6/30/2016 CS210-Summer 2005, Lecture 4 9 A Simple Array Based Implementation To pop: If isEmpty() is true then throw Exception Otherwise store S[t] in a local variable, assign null to S[t], decrement top and return local variable having the previous top. 6/30/2016 CS210-Summer 2005, Lecture 4 10 Algorithms Algorithm size(): return t+1 Algorithm pop(): if isEmpty() then Algorithm isEmpty(): return (t < 0) throw a EmptyStackException e <- S[t] Algorithm top(): S[t] = null if isEmpty() then t <- t - 1 throw a EmptyStackException return e return S[t] Algorithm push(o): if size() = N then throw a FullStackException t <- t + 1 S[t] <- o 6/30/2016 CS210-Summer 2005, Lecture 4 11 Analyzing the Array Based Stack Implementation Each of the stack methods in the array realization executes a constant number of statements involving arithmetic operations, comparisons and assignments. top() and pop() methods calls isEmpty(), which itself runs in constant time. In the implementation of Stack ADT each method runs in constant time. 6/30/2016 CS210-Summer 2005, Lecture 4 12 Analyzing the Array Based Stack Implementation 6/30/2016 Method Time size O(1) isEmpty O(1) top O(1) push O(1) pop O(1) CS210-Summer 2005, Lecture 4 13 A Drawback with the Array based implementation Array based implementation must assume a fixed upper bound N on the ultimate size of the stack. An application may actually need much less space than this in which case we would be wasting memory. Alternatively an application may need more space, in which case stack implementation may crash the application. Still in cases where we have a good estimate on the number of items to be stored in the stack, the array based implementation is hard to beat. 6/30/2016 CS210-Summer 2005, Lecture 4 14 Casting with a Generic Stack push(Object o) allows us to store any object namely Student object, Integer object, Account object and so on. This is because every class in Java inherits from Object class. pop() returns a reference of type Object back, no matter what the specific class of the object is. What is the solution? 6/30/2016 CS210-Summer 2005, Lecture 4 15 Reversing an Array using Stack A 5 10 8 6 3 1. push(5) 3 2. push(10) 6 3. push(8) 8 4. push(6) 10 5. push(3) 5 Stack S 1. B[0] = pop() B 3 6 8 10 5 2. B[1] = pop() 3. B[2] = pop() 4. B[3] = pop() 5. B[4] = pop() 6/30/2016 CS210-Summer 2005, Lecture 4 Stack S 16 Stacks in the Java Virtual Machine A Java program is typically compiled into a sequence of byte codes that are defined as machine instructions for Java Virtual Machine (JVM). By compiling Java code into the JVM byte codes, rather than the machine language of a specific CPU, a java program can be run on any computer that has JVM. 6/30/2016 CS210-Summer 2005, Lecture 4 17 The Java Method Stack A running java program has a private stack called the Java method stack which is used to keep track of local variables and other important information on methods as they are invoked during execution. JVM maintains a stack whose elements are descriptions of the currently active (nonterminated) invocations of methods. These descriptions are called frames. 6/30/2016 CS210-Summer 2005, Lecture 4 18 The Java Method Stack The JVM keeps a special variable, called the program counter, to maintain the address of the statement the JVM is currently executing in the program. At the top of the stack is the frame of the running method (method having control of the execution). Other elements in stack are frames of the suspended methods (methods waiting for another method to return control). 6/30/2016 CS210-Summer 2005, Lecture 4 19 The Java Method Stack bMethod: PC = 320 m= 7 aMethod: PC = 216 j=5 k=7 main: PC = 14 i=5 Java Stack 6/30/2016 14 main() { int i = 5; ….. aMethod ( i ); ….. } aMethod (int j) { int k = 7; ….. 216 bMethod(k); ….. } 320 bMethod (int m) { ….. } CS210-Summer 2005, Lecture 4 20 Applications of Stacks Implementation of function calls (Java method stack) Postfix Evaluation Infix to Postfix conversion Towers of Hanoi Problem Parenthesis Matching Types of Expression Infix Postfix Prefix 6/30/2016 CS210-Summer 2005, Lecture 4 21 Types of Expressions Normal way of expressing mathematical expressions is called infix form. E.g. 4 + 5 * 5 However we can also represent the above expression either by writing all operators before their operands or after them. 455*+ +4*55 6/30/2016 Postfix form (Reverse Polish Notation) Prefix form (Polish Notation) CS210-Summer 2005, Lecture 4 22 Advantages of Postfix Notation Parentheses are unnecessary Easy for a computer to evaluate the arithmetic expression. Examples: (a + (2 * b – 4 * c) / d) * (5 + e) In postfix form the formula becomes: a 2b*4c*-d/+5e+* 6/30/2016 CS210-Summer 2005, Lecture 4 23 Postfix Evaluation Algorithm while not end of postfix expression get next postfix item if item is operand then push (item) else if item is binary operator //op–binary op x <- pop() y <- pop() result <- x op y push (result) else if item is unary operator //op–unary op x <- pop() result <- op x push (result) 6/30/2016 CS210-Summer 2005, Lecture 4 24 Example 6523+8*+3+* The first item is operand (6), so it is pushed on to stack 3 So does 5 , 2 and 3. 2 5 6 Next item is + (binary operator). So 2 and 3 are popped from the stack and their sum “5” is pushed onto stack. 5 5 6 6/30/2016 CS210-Summer 2005, Lecture 4 25 Example (contd.) 8 8 5 5 5 5 6 Next 8 is pushed. Next is *. Next is +. Next 3 is pushed. 3 45 6 Next is +. 48 6 6/30/2016 40 5 6 45 6 CS210-Summer 2005, Lecture 4 26 Example (contd.) Next is *. 288 Now there are no more items and there is a single value on the stack, representing the final answer 288. Note the answer was found with a single traversal of the postfix expression, with the stack being used as a kind of memory storing values that are waiting for their operands. 6/30/2016 CS210-Summer 2005, Lecture 4 27 Infix to Postfix Conversion Algorithm Initialize output to empty while not end of infix expression get next infix item if item is operand then append item to output else if item = ‘(‘ push (item) else if item = ‘)’ x <- pop() while x != ‘(‘ append x to output x <- pop() else if item is operator while (precedence(stack top)>= precedence(item)) x <- pop() append x to output push (item) while (stack not empty) x <- pop() append x to output 6/30/2016 CS210-Summer 2005, Lecture 4 28 Example a + b * c + (d * e + f) * g 1. Output = “” 2. Output = “a” 3. Stack + Output = “a b” 4. Stack * + Output = “a b c” 5. Stack + Output = “a b c * +” 6. Stack ( + Output = “a b c * + d” * ( + Output = “a b c * + d e” 7. Stack 6/30/2016 CS210-Summer 2005, Lecture 4 29 Example (contd.) + ( + Output = “a b c * + d e * f” Stack + Output = “a b c * + d e * f +” 10. Stack * + Output = “a b c * + d e f + g” 11. Stack 8. Stack 9. 6/30/2016 Output = “a b c * + d e f + g * +” CS210-Summer 2005, Lecture 4 30 Parenthesis matching We are tempted to think of simplest solution: Count all the left and right parenthesis. If they are equal, they match. (??) ())(() : Simple solution will accept this. We need something more complicated. Use stack 6/30/2016 CS210-Summer 2005, Lecture 4 31 Parenthesis Matching Algorithm while not end of expression get next item if item is left parenthesis then push (item) else if item is right parenthesis if stack is empty then return false if pop() does not match item then return false if stack is empty then return true else return false 6/30/2016 CS210-Summer 2005, Lecture 4 32 Queues Queue is a container of objects that are inserted and removed according to the first-in first-out (FIFO) principle. Objects can be inserted into a queue at any time, but only the objects that has been in the queue the longest can be removed at any time Objects enter the queue at the rear and are removed from the front. 6/30/2016 CS210-Summer 2005, Lecture 4 33 Queue ADT Queue ADT supports following methods: enqueue(o): Insert object o at the rear of the queue. Input: Object o Output: None dequeue(): Remove and return from the queue the object at the front. Error occurs if the queue is empty. 6/30/2016 Input: None Output: Front object CS210-Summer 2005, Lecture 4 34 Queue ADT size(): Return the number of objects in the queue isEmpty(): Return a boolean indicating if the queue is empty. Input: none Output: Integer (total number of objects) Input: None Output: boolean (true if queue is empty, false otherwise) front(): Return but do not remove, the front object in the queue. Error occurs if the queue is empty. Input: None Output: Front object 6/30/2016 CS210-Summer 2005, Lecture 4 35