Stacks & Queues Last in First out LIFO How a Stack Works 3 main operations 1. Push → inserts a new elements at the top of the stack 2. Pop → removes & returns the element at the top of the stack 3. Peek → returns the element at the top of the stack How a Stack Works At first, a Stack is an empty container. How a Stack Works - Push Push ( 13 ) 13 How a Stack Works - Push Push ( 2 ) 2 13 How a Stack Works - Push Push ( -8 ) -8 2 13 How a Stack Works - Pop -8 Pop ( ) 2 Removes & 13 Returns the value How a Stack Works - Pop 2 Pop ( ) Removes & 13 Returns the value How a Stack Works - Pop 13 Pop ( ) Removes & Returns the value How a Stack Works - Pop Stack is empty You can NOT Pop any more elements Pop ( ) Removes & Returns the value How a Stack Works - Peek Peek ( ) -8 2 13 -8 Returns the value at the top How a Stack Works - Peek - one more time Still returns Peek ( ) -8 2 13 -8 Returns the value at the top Your Turn - Show how the Stack looks after executing all the following steps. Push ( 7 ) Push ( 6 ) Push ( 5 ) Pop ( ) Peek ( ) Pop ( ) Push ( 6 ) Pop ( ) Peek ( ) Implementing a Stack using an Array maxSize = 6; Implementing a Stack using an Array 0 5 0 4 0 3 0 2 0 1 0 0 maxSize = 6; int [ ] myStack = new int [ maxSize ]; Implementing a Stack using an Array 0 5 0 4 0 3 0 2 0 1 0 0 maxSize = 6; int [ ] myStack = new int [ maxSize ]; int top = -1; top = -1 Implementing a Stack using an Array 0 5 0 4 0 3 0 2 0 1 0 0 Push ( -8 ) top = -1 Implementing a Stack using an Array 0 5 0 4 0 3 0 2 0 1 Push ( -8 ) 1. Increment top ⇒ top++; top = 0 0 0 Implementing a Stack using an Array 0 5 0 4 0 3 0 2 0 1 Push ( -8 ) 1. Increment top ⇒ top++; 2. Update the element at index top with -8 top = 0 -8 0 ⇒ myStack [ top ] = -8; Implementing a Stack using an Array 0 5 0 4 0 3 0 2 12 1 -8 0 Push ( 12 ) 1. Increment top ⇒ top++; top = 1 2. Update the element at index top with 12 ⇒ myStack [ top ] = 12; Implementing a Stack using an Array 0 5 0 4 0 3 19 2 12 1 -8 0 Push ( 19 ) 1. Increment top top = 2 ⇒ top++; 2. Update the element at index top with 12 ⇒ myStack [ top ] = 12; Implementing a Stack using an Array 0 5 0 4 0 3 19 2 12 1 -8 0 Peek ( ) top = 2 Implementing a Stack using an Array 0 5 0 4 0 3 19 2 12 1 -8 0 Peek ( ) 1. Return the element at index top top = 2 ⇒ return myStack [ top ] ; Implementing a Stack using an Array 0 5 0 4 0 3 19 2 12 1 -8 0 Pop ( ) top = 2 Implementing a Stack using an Array 0 5 0 4 0 3 19 2 12 1 -8 0 Pop ( ) 1. Keep a copy of the element at index top top = 2 ⇒ int x = myStack [ top ] ; Implementing a Stack using an Array 0 5 0 4 0 3 19 2 12 1 -8 0 Pop ( ) 1. Keep a copy of the element at index top ⇒ int x = myStack [ top ] ; top = 1 2. Remove the element at index top ⇒ top -- ; Implementing a Stack using an Array 5 Pop ( ) 0 4 1. 0 3 19 2 12 1 -8 19 0 Keep a copy of the element at index top ⇒ int x = myStack [ top ] ; 2. Remove the element at index top top = 1 ⇒ top -- ; 3. Return the copy 0 ⇒ return x; The Stack Class in Java class Stack { int maxSize; int [] myStack; int top; Stack ( ) { maxSize = 100; myStack = new int [ maxSize ]; top = -1; } // push, pop, and peek functions } The Stack Class in Java class Stack { int maxSize; int [] myStack; int top; Stack ( ) { maxSize = 100; myStack = new int [ maxSize ]; top = -1; } // push, pop, and peek functions } void Push( int element ) { top++; myStack [ top ] = element; } The Stack Class in Java class Stack { int maxSize; int [] myStack; int top; Stack ( ) { maxSize = 100; myStack = new int [ maxSize ]; top = -1; } // push, pop, and peek functions } int Pop( ) { int x = myStack [ top ]; top--; return x; } The Stack Class in Java class Stack { int maxSize; int [] myStack; int top; Stack ( ) { maxSize = 100; myStack = new int [ maxSize ]; top = -1; } // push, pop, and peek functions } int Peek( ) { int x = myStack [ top ]; return x; } The Stack Class in Java class Stack { int maxSize; int [] myStack; int top; Stack ( ) { maxSize = 100; myStack = new int [ maxSize ]; top = -1; } // other useful functions → isEmpty } boolean isEmpty( ) { if ( top == -1) return true; else return false; } The Stack Class in Java class Stack { int maxSize; int [] myStack; int top; Stack ( ) { maxSize = 100; myStack = new int [ maxSize ]; top = -1; } // other useful functions → isFull } boolean isFull( ) { if ( top == maxSize - 1) return true; else return false; } Testing The Stack Class class StackTester { public static void main ( String [] args ) { Stack theStack = new Stack ( ); theStack.push( 20 ); theStack.push( 40 ); theStack.push( 60 ); theStack.push( 80 ); while( ! theStack.isEmpty( ) int value = theStack.pop(); System.out.println( value ); } } } ) { Use the 2 Stacks S1 & S2 to display the contents of S1 in a reverse order ( From Bottom to top ) e d c b a S1 Use the 2 Stacks S1 & S2 to display the contents of S1 in a reverse order ( From Bottom to top ) S2.push ( S1.pop () ); e d c b a S2.push ( S1.pop () ); S2.push ( S1.pop () ); S2.push ( S1.pop () ); S2.push ( S1.pop () ); Sout ( S2.pop () ); Sout ( S2.pop () ); Sout ( S2.pop () ); Sout ( S2.pop () ); Sout ( S2.pop () ); Use the 2 Stacks S1 & S2 to display the contents of S1 in a reverse order ( From Bottom to top ) e d c b a While ( ! S1.isEmpty() ) S2.push ( S1.pop () ); While ( ! S2.isEmpty() ) Sout ( S2.pop () ); Big O for the Stack Push ⇒ O ( 1 ) Pop ⇒ O ( 1 ) Peek ⇒ O ( 1 ) Search ⇒ O ( N ) Stacks & Queues First in First out FIFO How a Queue Works 3 main operations 1. insert → inserts a new elements at the rear of the queue 2. remove → removes & returns the element at the front of the queue 3. Peek → returns the element at the front of the queue How a Queue Works Head OR Front Tail OR Rear At first, a Queue is an empty list. How a Queue Works - Enqueue 29 Head OR Front Tail OR Rear Enqueue ( 29 ) How a Queue Works - Enqueue 29 80 Head OR Front Tail OR Rear Enqueue ( 80 ) How a Queue Works - Enqueue 29 80 -78 Head OR Front Tail OR Rear Enqueue ( -78 ) How a Queue Works - Enqueue 29 80 -78 6 Head OR Front Tail OR Rear Enqueue ( 6 ) How a Queue Works - Dequeue 29 80 -78 6 Head OR Front Tail OR Rear Dequeue ( ) Removes the element @ the front and Returns it. How a Queue Works - Dequeue 80 -78 6 Head OR Front Tail OR Rear Dequeue ( ) Removes the element @ the front and Returns it. How a Queue Works - Peek -78 6 Head OR Front Tail OR Rear Peek ( ) Returns the element @ the front. Does NOT remove it Your Turn - Show how the Queue looks after executing all the following steps. Enqueue ( 7 ) Enqueue ( 6 ) Enqueue ( 5 ) Dequeue ( ) Peek ( ) Dequeue ( ) Enqueue ( 6 ) Dequeue ( ) Peek ( ) Your Turn - Show the output of the following program. Stack s = new Stack(); q.Enqueue( 6 ); Queue q = new Queue(); System.out.print ( s.Push( 7 ); q.DeQueue( ) ); s.Push( 6 ); s.Push( q.DeQueue( ) ); s.Push( 5 ); System.out.print ( s.Pop( ) ); System.out.print ( s.Pop( ) ); System.out.print ( s.Pop( ) ); q.Enqueue( s.Pop( ) ); q.Enqueue( 5 ); Implementing a Queue using an Array 0 0 0 0 0 0 0 Rear Front num_items = 0 At first, a Queue is an empty container. Implementing a Queue using an Array 29 0 0 0 0 Rear Front Enqueue ( 29 ) num_items = 1 0 0 Implementing a Queue using an Array 29 50 0 0 0 Rear Front Enqueue ( 50 ) num_items = 2 0 0 Implementing a Queue using an Array 29 50 -78 0 0 Rear Front Enqueue ( -78 ) num_items = 3 0 0 Implementing a Queue using an Array 29 50 -78 13 0 Rear Front Enqueue ( 13 ) num_items = 4 0 0 Implementing a Queue using an Array 29 50 -78 13 80 Rear Front Enqueue ( 80 ) num_items = 5 0 0 Implementing a Queue using an Array 29 50 -78 13 4 Rear Front Enqueue ( 4 ) num_items = 6 80 0 Implementing a Queue using an Array 29 50 -78 13 4 Rear Front Dequeue ( ) num_items = 5 80 0 Implementing a Queue using an Array 29 50 -78 13 num_items = 4 4 Rear Front Dequeue ( ) 80 0 Implementing a Queue using an Array 29 50 -78 13 num_items = 3 4 Rear Front Dequeue ( ) 80 0 Implementing a Queue using an Array 29 50 -78 13 num_items = 4 4 8 Rear Front Enqueue ( 8 ) 80 Implementing a Queue using an Array 29 50 -78 13 80 num_items = 4 8 Rear Front Enqueue ( 6 ) 4 Implementing a Queue using an Array 29 50 -78 13 80 num_items = 4 8 Rear Front Rear Enqueue ( 6 ) 4 Implementing a Queue using an Array 29 50 -78 13 80 Front Rear Enqueue ( 6 ) num_items = 4 4 8 Implementing a Queue using an Array 6 50 -78 13 80 Front Rear Enqueue ( 6 ) num_items = 4 4 8 This is called Wrap-around and we need it to be able to insert or delete more elements after 1. The rear has reached the end of the array. 2. The front has reached the end of the array. The Queue Class in Java class Queue { int maxSize; int [] myQueue; int front, rear, num_items; Queue ( int size ) { maxSize = size ; myQueue = new int [ maxSize ]; front = 0; rear = -1; num_items = 0; } // enqueue, dequeue // and peek functions } The Queue Class in Java class Queue { int maxSize; int [] myQueue; int front, rear, num_items; Queue ( int size ) { maxSize = size ; myQueue = new int [ maxSize ]; front = 0; rear = -1; num_items = 0; } // enqueue, dequeue // and peek functions } void Enqueue( int elm ) { if ( rear == maxSize - 1 ) rear = -1 ; rear++; myQueue[ rear ] = elm; num_items++; } The Queue Class in Java class Queue { int Dequeue( ) { int maxSize; int elm = myQueue[ front ]; int [] myQueue; front++; int front, rear, num_items; if ( front == maxSize) Queue ( int size ) { front = 0 ; maxSize = size ; myQueue = new int [ maxSize ]; num_items--; front = 0; return elm; rear = -1; } num_items = 0; } // enqueue, dequeue // and peek functions } The Queue Class in Java class Queue { int Peek( ) { int maxSize; int elm = myQueue[ front ]; int [] myQueue; int front, rear, num_items; return elm; Queue ( int size ) { } maxSize = size ; myQueue = new int [ maxSize ]; front = 0; rear = -1; num_items = 0; } // enqueue, dequeue // and peek functions } The Queue Class in Java class Queue { boolean isEmpty( ) { int maxSize; if ( num_items == 0 ) int [] myQueue; return true; int front, rear, num_items; else Queue ( int size ) { return false; maxSize = size ; } myQueue = new int [ maxSize ]; front = 0; rear = -1; num_items = 0; } // Other useful functions } The Queue Class in Java class Queue { boolean isFull( ) { int maxSize; if ( num_items == maxSize ) int [] myQueue; return true; int front, rear, num_items; else Queue ( int size ) { return false; maxSize = size ; } myQueue = new int [ maxSize ]; front = 0; rear = -1; num_items = 0; } // Other useful functions } The Queue Class in Java class Queue { int size( ) { int maxSize; return num_items; int [] myQueue; } int front, rear, num_items; Queue ( int size ) { maxSize = size ; myQueue = new int [ maxSize ]; front = 0; rear = -1; num_items = 0; } // Other useful functions } Testing The Queue Class class QueueTester { public static void main ( String [] args ) { Queue theQueue = new Queue ( 3 ); theQueue.Enqueue( 10 ); theQueue.Enqueue( 20 ); theQueue.Dequeue(); theQueue.Enqueue( 30 ); theQueue.Enqueue( 40 ); // wraps around while( ! theQueue.isEmpty( ) ) int value = theQueue.Dequeue(); System.out.println( value ); } } } { Testing The Queue Class class QueueTester { public static void main ( String [] args ) { Queue theQueue = new Queue ( 3 ); theQueue.Enqueue( 10 ); theQueue.Enqueue( 20 ); theQueue.Enqueue( 30 ); theQueue.Dequeue(); theQueue.Dequeue(); theQueue.Dequeue(); theQueue.Dequeue(); } } // 10 // 20 // 30 Testing The Queue Class class QueueTester { public static void main ( String [] args ) { Queue theQueue = new Queue ( 3 ); theQueue.Enqueue( 10 ); theQueue.Enqueue( 20 ); theQueue.Enqueue( 30 ); theQueue.Dequeue(); theQueue.Dequeue(); theQueue.Dequeue(); theQueue.Dequeue(); // 10 // 20 // 30 // 10 } } We didn’t check if the queue is empty or not Big O for the Queue Enqueue ⇒ O ( 1 ) Dequeue ⇒ O ( 1 ) Peek ⇒ O ( 1 ) Search ⇒ O ( N )