CS62 - Spring 2021 - Class 10

Example code in this lecture

   StacksAndQueues

Lecture notes

  • administrative
       - Assignment 4
       - midterm in lab next Wednesday
          - review next Tuesday
          - can bring one page of notes (double-sided)
          - will post practice problems with solutions
             - study first!
             - then try the practice problems
             - try hard not to look at the solutions
             - find other ways to check your answers, like running your programs

  • Linear structures
       - similar to lists in that there is a sequential nature to the data
       - unlike lists, though, we can only add and remove items, but cannot access items by index or iterate through the items
       - look at Linear interface in StacksAndQueues code
          - we can:
             - add items
             - remove an item (and return it)
             - take a look at the next item
             - see if we have items left
          - notice that we don't have any notion of an index

  • stacks
       - Last In First Out (LIFO)
       - two basic operations: push and pop
          - push adds another item on to the top of the stack
          - pop removes the item on the top of the stack
       - think about a stack of plates at a buffet. The last plate to be put on top will be the first plate to be removed.
          - stacks usually grow up
          - everything happens on the top

       - look at the Stack interface in StacksAndQueues code
          - push
          - pop
          - peek (when we just want to see what's on top, but don't want to modify the stack)
          - empty

       - how could we implement this?
          - Linked list
             - always just manipulate the head of the beginning of the linked list
             - to push an item, just add it to the front
             - to remove an item, remove it from the front
             - look at LinkedStack in StacksAndQueues code
             - singly linked or doubly linked?
             - runtime of the different operations:
                - push: O(1)
                - pop: O(1)
                - peek: O(1)
                - empty: O(1)
          - ArrayList
             - where should the top of the stack go?
                - remember we'll be adding and deleting at the top of the stack
                - put the top of the stack at the END of the ArrayList
             - to push an item, add it to the end of the ArrayList
             - to remove an item, remove it from the end of the ArrayList
             - look at ArrayListQueue in StacksAndQueues code
             - runtime of the different operations:
                - push: O(1) (amortized)
                - pop: O(1)
                - peek: O(1)
                - empty: O(1)

          - which is better?
             - ArrayList is "amortized" O(1) run-time, however, any individual push operation could be O(n)
             - Memory trade-off is less clear
                - ArrayList could have lots of "open" memory
                - LinkedList has an extra reference for each data item

  • queues
       - if you're from the UK, you call a "line" (like waiting in line) a queue
       - First In First Out (FIFO)
       - two basic operations: enqueue and dequeue
          - enqueue adds another item on the the end of the queue
          - dequeue removes an item from the front of the queue
       - notice that like a stack the only way we manipulate the data is by adding and removing items, the difference is where we add and remove the items

       - look at the Queue interface in StacksAndQueues code
          - enqueue
          - dequeue
          - peek (when we just want to see what's on top, but don't want to modify the stack)
          - empty

       - how could we implement this?
          - Linked list
             - where should we add and remove items?
                - singly linked list with tail reference:
                   - add to the back
                   - remove from the front
                - doubly linked list with tail pointer: doesn't matter :)
             - look at LinkedQueue in StacksAndQueues code
             - runtime: O(1)

          - ArrayList based
             - where should we add and remove the items?
                - if we add them to the back, then the remove (dequeue) operation is going to be expensive
                - if we add them to the front, then the add (enqueue) operation is going to be expensive
             - we'll add at the back again and remove them from the front
             - look at LinkedQueue in StacksAndQueues code
             - runtime of different operations:
                - enqueue: O(1)
                - dequeue: O(n)
                - peek: O(1)
                - empty: O(1)
             - Even though both implement the List interface, it makes a difference which underlying data structure we use... pick the right one!

  • look at StackVQueue class in StacksAndQueues code
       - what will testStack and testQueue print out?
          - testStack
             daikon
             carrot
             banana
             apple

             (LIFO: last in first out)
          - testQueue
             apple
             banana
             carrot
             daikon

             (FIFO: first in first out)
       - What types of objects can we pass to testStack?
          - Anything that implements the Stack interface (ArrayListStack or LinkedStack)
       - Will the answer change depending on what we pass in?
          - Not if we've implemented them correctly :)
          - They both are stacks, just different ways of representing them
       - What types of objects can we pass to testLinear?
          - Anything that implements the Linear interface
          - All of our stacks and queue implement this interface
          - this allows us to pass either a stack OR a queue!

  • Applications
       - What are stacks and queues good for?

       - stacks
          - run-time (or call) stack example
             - we can write a simple method sum and follow it through the call-stack using the debugger
             public static int sum(int n){
                String temp = "Num: " + n;
                System.out.println(temp);
          
                if( n <= 1 ){
                   return 1;
                }else{
                   return n + sum(n-1);
                }
             }
          - searching
          - parsing (linguistics, code)

       - queues
          - scheduling tasks
             - which process should run next
          - modeling real world phenomena (lines show up in lots of places)
          - searching

  • Stacks/queues in Java:
       - dequeue interface: https://docs.oracle.com/javase/7/docs/api/java/util/Deque.html
       - Common classes that implement this interface:
          - ArrayDequeue
          - LinkedList