Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 / 23 COP 3540 Data Structures with OOP Chapter 4 Stacks and Queues.

Similar presentations


Presentation on theme: "1 / 23 COP 3540 Data Structures with OOP Chapter 4 Stacks and Queues."— Presentation transcript:

1 1 / 23 COP 3540 Data Structures with OOP Chapter 4 Stacks and Queues

2 2 / 23 A Different Kind of Structure  Stacks, queues, and priority queues – different kinds of storage structures.  Different data structures have different sets of problems that they are most suited to representing.  Consider Arrays – as a data storage structure:  very useful.  easy to insert into, delete from, and search for specific items.

3 3 / 23 Access (interface)  Arrays: theoretically, access is immediate via index or by searching through cells sequentially.  If ordered, can access more quickly via binary search  Only one item can be accessed.  ‘That’ is the interface.’  In abstract data structures (stacks, queues, trees, priority queues), real access (that is, how do we get to it…) is:  defined a bit differently and is  controlled by an interface that is normally not visible to the user.

4 4 / 23 Stacks  Stacks - access to only one item at a time.  Think of a stack of dishes.  It is a LIFO data structure.  Extremely useful tool in programming:  Evaluate parenthesized expressions,  Evaluate arithmetic expressions even with lots of parentheses,  Traversing binary trees,  Searching vertices of a graph, and much more.  Consider stacked-based architecture and calling sequences / return addresses….

5 5 / 23 Stacks  Stacks are conceptual (logical), abstract structures.  We can envision them.  Really no such thing as a real stack!  But we are interested in how we can implement the logical structure on a machine.  Basic operations – four. Know these!:  Push (onto top of stack)  Pop (top item off of stack)  Stack overflow (stack full) – cannot push! (normally error condition or special processing needed. Same for underflow…)  Stack underflow (stack empty) – cannot pop!  Let’s look at Java Code for a Stack

6 6 / 23 class StackApp { public static void main(String[] args) { StackX theStack = new StackX(10); // makes new stack of size 10. //note: argument sent to the Stack object for use by constructor // note: we DO NOT KNOW how the stack actually looks!!!!! // that is, we do NOT know what the underlying data structure looks like!!!!! theStack.push(20); // push items onto stack theStack.push(40); // These are ‘logical’ operations!!! theStack.push(60); (How to evaluate??) theStack.push(80); while( !theStack.isEmpty() ) // until it's empty, delete item from stack { long value = theStack.pop();// what is author doing here??? System.out.print(value); // display it System.out.print(" "); } // end while System.out.println(""); } // end main() } // end class StackApp

7 7 / 23 // stack.java demonstrates stacks Note: I have taken liberties with the ‘{‘ to fit this code on one page. class StackX { private int maxSize; // size of stack array private long[] stackArray; // recall: ‘instance variables’ private int top; // top of stack //-------------------------------------------------------------- public StackX(int s) // constructor // (How can you tell this is the Constructor??) { // ONLY NOW CAN WE SEE STACK IS IMPLEMENTED AS AN ARRAY! maxSize = s; // set array size // Recall: ‘ local variables’ Where are they known?? stackArray = new long[maxSize]; // Create array; ARRAY IS OF ‘LONGS’ //’long’ is a primitive data structure; how longs are implemented and // accessed are defined in system. No need for separate class for this. top = -1; // no items yet } // end StackX()DISCUSS //-------------------------------------------------------------- public void push(long j) { // put item on top of stack stackArray[++top] = j; // increment top, insert item //  tell me exactly how this works!! } // end push() // How many operators do you see? //-------------------------------------------------------------- public long pop() { // take item from top of stack return stackArray[top--]; // access item, decrement top// tell me exactly how this works!! }// end pop ()//recall: What is the ‘other kind’ of variable????? //-------------------------------------------------------------- public long peek() { // peek at top of stack return stackArray[top];// when we come into this object, the pointer is } // end peek() // pointing to the topmost element. //-------------------------------------------------------------- public boolean isEmpty() { // true if stack is empty return (top == -1);// tell me exactly how this works!! } // end isEmpty() //-------------------------------------------------------------- public boolean isFull() { // true if stack is full //Ah ha! We see (above) that the Stack is ‘implemented’ as return (top == maxSize-1);// an array! But it doesn’t have to be!!!!! } } // end class StackX// Storage structure transparent to client. Good!!! Why???

8 8 / 23 Notes:  Always check to see if there are items on the stack before popping the stack or if there is room before pushing the stack  isFull?  isEmpty?  Appropriate error routines are up to the developer / user  Best approach: in Push() and Pop(), check for isEmpty and isFull within these methods.  Regardless, they need to be specified.  Go through Reversing a Word routine in book.  We will look at Delimiter Matching.

9 9 / 23 Delimiter Matching  Stacks are used a lot to temporarily store tokens like a char or parts of arithmetic expressions having parentheses in them and later retrieve them when we have a number of delimiters.  ‘Delimiters’ = normally special characters (e.g. commas, white space, braces, brackets, parentheses, …)  They normally set something off or bracket something.  Delimiters (but not white spaces) must always ‘balance’ – the first right parenthesis balances the ‘most recent’ unbalanced left parenthesis, etc.

10 10 / 23 Delimiter Matching – more  Consider: x = (a+b*(c/d**4-e/(2*a)-5)-14.2/g);  How do you and the machine evaluate this?  (You will see this again.)  You absolutely need to know the order of evaluation of most common operators.  Note: this ‘order of evaluation’ (operator precedence) is basic to all programming languages!!

11 11 / 23 Delimiters – the Algorithm  Algorithm: tries to evaluate as it goes.  But when it encounters an opening delimiter, it must process it and may push a token onto a stack only to pop it later.  When the algorithm encounters closing delimiter or operator of lesser precedence), the algorithm may  pop the stack and  perform the evaluation thus creating a temporary (or partial) value,  May push temporary result ‘back’ onto stack if more terms follow.  If no closing delimiter is found (or if unbalanced), syntax error!  For pairs of delimiters, such as ‘parentheses’ the one opened last  closed first.  If different delimiters are used (brackets, parentheses, etc.) then the correct delimiter must be found, if syntax of the expression is valid.  Different delimiters? Parentheses; brackets for indexes …  If syntax is invalid,  compilation error!  Let’s look at some code.

12 12 / 23 // brackets.java// Discuss: stack for handling string input / evaluations… import java.io.*; // for I/O// Discuss each method briefly. class StackX { private int maxSize; //Here’s my ‘instance’ data, right? private char[] stackArray; //declares a pointer (reference), stackArray, to a char array private int top;// where the array itself is not yet allocated / built. //-------------------------------------------------------------- public StackX(int s) // constructor {// when object of class StackX is created in its client, maxSize = s;// BracketChecker, size of the stack is passed to this Constructor stackArray = new char[maxSize]; // Constructor uses this parameter to determine size of array object. top = -1; // Stack object, just created, is empty, so top of stack is set to -1, an invalid array reference. } // end StackX() //-------------------------------------------------------------- public void push(char j) // put item on top of stack no change { stackArray[++top] = j;// Exactly how does this work for first item? Values of top? }//end push() //-------------------------------------------------------------- public char pop() // take item from top of stack { return stackArray[top--];// Note top is decremented AFTER item is popped! } // end pop() //-------------------------------------------------------------- public char peek() { // peek at top of stack // note: encapsulation; see stack and // methods that process. return stackArray[top]; } // end peek() //-------------------------------------------------------------- public boolean isEmpty // cut off for space…

13 13 / 23 class BracketChecker { private String input; // input string public BracketChecker(String in) // constructor; When object is created, a String is { input = in; }// passed to it. Becomes value of ‘input.’ //-------------------------------------------------------------- public void check() { int stackSize = input.length(); // get max stack size. Where does input.length() come from? StackX theStack = new StackX(stackSize); // make stack Creates stack object of size stackSize. Do you see??? // Stack (array) is declared to be the size of input string. for(int j=0; j<input.length(); j++) { // Get chars in turn char ch = input.charAt(j); // get a charWhere does input.charAt(j) come from? switch(ch) { case '{': // opening symbols case '[': // ROUTINE IS ONLY CHECKING FOR BALANCING DELIMITERS. IS NOT EVAL… case '(': theStack.push(ch); // push the symbol onto the Stack. Check it out. break; case '}': // closing symbols case ']': case ')': if( !theStack.isEmpty() ) // if stack not empty and came in with ‘closing’ delimiter… { char chx = theStack.pop(); // pop and check if( (ch=='}' && chx!='{') || ch==']' && chx!='[') || (ch==')' && chx!='(') ) System.out.println("Error: "+ch+" at "+j); } else // prematurely empty System.out.println("Error: "+ch+" at "+j); break; default: // no action on other characters. Routine is only looking for delimiters; not evaluating; checking!! break; } // end switch } // end for // at this point, all characters have been processed if( !theStack.isEmpty() ) System.out.println("Error: missing right delimiter"); } // end check() } // end class BracketChecker

14 14 / 23 class BracketsApp { public static void main(String[] args) throws IOException { String input; while(true)//Notice indentation and scope terminators. { System.out.print ( "Enter string containing delimiters: "); input = getString(); // read a string from keyboard Note the static method in Main if( input.equals("") ) // quit if [Enter] break // otherwise, make a BracketChecker BracketChecker theChecker = new BracketChecker(input); // OK. Now, this creates an object of type BracketChecker. Object name is theChecker. // Pass the string, ‘input’ to the Constructor. theChecker.check(); // calls check() within theChecker. } // end while // the check() method } // end main() //-------------------------------------------------------------- public static String getString() throws IOException { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); String s = br.readLine(); return s; } // end getString() //-------------------------------------------------------------- } // end class BracketsApp // note the DESIGN! Note how all of these objects have their // responsibilities and how they collaborate to provide the needed functionality; reusability too.

15 15 / 23 Stack as a Conceptual Aid  The notion (vision) of a stack is simple.  Once a Stack (very reusable) is set up, you don’t have to keep track of indices  But there is limited access to the stack elements via push() and pop()  Efficiency:  Push() and pop() take O(1) time – a constant. Why??  No dependency on number of items in stack.  No comparisons or moves necessary.  For many applications, this is a very convenient logical data structure.

16 16 / 23 Queues  A FIFO data structure; is a ‘line.’  A Stack is a LIFO data structure.  What is a FISH data structure?  A queue  another conceptual data structure (logical data structure)  can be implemented using an array, linked list or other structure.  Queues: VERY useful for many different applications.  Typically used to model waiting lines, such as planes waiting to take off; waiting lines at McDonalds, etc. and much more!  Many queues in your operating system: Print queues Job queues Ready queues Keyboard queues – data not lost; just ‘queued up.’

17 17 / 23 Queues - terminology  Queues  data entered in one end  Data extracted from the other end, as envisioned.  Thus, our queue operations are  insert() and remove() insert() at the rear (back or tail) of the queue remove() at the front (head) of the queue.  These are reasonably common terms.  Rear of queue is the tail (back or tail or end)  Front of queue is head.  We will use: insert, remove, front and rear.

18 18 / 23 Queues – more  Potential error conditions  Attempt to remove an item from an empty queue?? Want ‘empty queue’ message returned.  Attempt to insert an item into a ‘full queue’ Want full queue message returned.  As in a Stack, we must ‘create’ the Queue.  Can also have Circular Queues: extremely useful!  Must be careful to keep track of the front and rear of the queue so that they do not wrap!  Consider: Java code for a Queue.

19 19 / 23 class QueueApp { public static void main(String[] args) { Queue theQueue = new Queue(5); // queue holds 5 items; Creates Queue theQueue and // passes a 5 as argument to theQueue’s Constructor. theQueue.insert(10); // insert 4 items theQueue.insert(20); theQueue.insert(30); theQueue.insert(40); theQueue.remove(); // remove 3 items theQueue.remove(); // (10, 20, 30) theQueue.remove(); theQueue.insert(50); // insert 4 more items theQueue.insert(60); // (wraps around) theQueue.insert(70); theQueue.insert(80); while( !theQueue.isEmpty() ) // remove and display all items. { long n = theQueue.remove(); // (40, 50, 60, 70, 80) System.out.print(n); System.out.print(" "); } // end while() System.out.println(""); } // end main() } // end class QueueApp ////////////////////////////////////////////////////////////////

20 20 / 23 // Queue.java class Queue { // Please note my moving of ‘{‘ and a few other things to poor spots – in the interest of space... private int maxSize; private long[] queArray;// reference to an array of ‘longs.’ private int front, rear, nItems; public Queue (int s) { // constructor  Note: size and structure of queue determined here. User does not maxSize = s; // see (or care) how queue is implemented. (See: array here. queArray = new long[maxSize];Note: Constructor is passed desired queue size from client. front = 0;Note: See instance and local variables?? rear = -1;Note: Here’s the queue; implemented as an array; front and rear nItems = 0; and number of Items setup and initialized. } // end Constructor public void insert(long j) { // put item at rear of queue if(rear == maxSize-1) // deals with wraparound //Note: insert() FIRST checks to see if there’s room for an insert. rear = -1;If rear is at maxSize-1, then we need to wrap to 0. queArray[++rear] = j; // increment rear and insertSo rear is set to -1 and it is set to 0 in this statement. nItems++; // one more item // note: number of items in queue is incremented. } // end insert() public long remove() { // take item from front of queue long temp = queArray[front++]; // get value and increments front //Note: creates a temp variable, temp, and moves if (front == maxSize) // deal with wraparound// the queue item into it and increments front pointer. front = 0;// it then checks to see if the new value causes wrap. nItems--; // one less item// Lastly, it decrements the queue size; returns temp. return temp; } // end remove() public long peekFront() { // peek at front of queue return queArray[front]; } // end peek() public boolean isEmpty() { // true if queue is empty // Do you see a problem with insert() ? return (nItems==0); } // end isEmpty() public boolean isFull() { // true if queue is full return (nItems==maxSize); } // end isFull() public int size() // number of items in queue return nItems; } // end size() } // end class Queue

21 21 / 23 Efficiency of Queues  insert() and remove() are considered O(1) times; that is, a constant. (immediate!)  Always know the value of the appropriate index  Simply a matter of ‘inserting’ or ‘removing’ at that point.  Just about simply inserting or removing and a minor change in value of front or rear (unless we wrap).  Deques  A double-ended queue  Can insert() and delete() from either end. Can insertLeft() and insertRight(), etc.  Know it is there and is quite useful and versatile. Look for it if you need it.

22 22 / 23 Questions?


Download ppt "1 / 23 COP 3540 Data Structures with OOP Chapter 4 Stacks and Queues."

Similar presentations


Ads by Google