CS62 - Spring 2011 - Lecture 12

  • video
       - http://www.youtube.com/watch?v=k4RRi_ntQc8

  • quiz on Friday

  • review of different List implementations
       - ArrayList
          - get, set and append are fast
       - LinkedLists
          - singly linked list with only head pointer
             - addFirst, removeFirst are fast
          - singly linked list with tail pointer
             - addLast is also fast
          - circular linked lists
             - do we need the tail pointer?
                - circularly linked lists hook the nextElement of the last element in the list to the first
                - keep track of the tail pointer only (i.e. no head)
             - addLast is also fast
          - doubly linked lists
             - removeLast is also fast
             - anything else?
             - if we happened to have reference to a node internal to the list, we could insert and remove at that location efficiently
             - when could this happen?
                - build it in as part of the data structure
                - iterator

  • 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.
       - draw a picture
          - stacks usually grow up
          - everything happens on the top
       - what are they used for?
          - 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)
       - 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)
          - isEmpty
       - 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)
                - isEmpty: 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 ArrayListStack in StacksAndQueues code
             - runtime of the different operations:
                - push: O(1)
                - pop: O(1)
                - peek: O(1)
                - isEmpty: O(1)
          - which is better?
             - ArrayList are "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
       - java.util.Stack (http://java.sun.com/j2se/1.5.0/docs/api/java/util/Stack.html)

  • 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
       - draw a picture
       - what are they used for?
          - scheduling tasks
             - which process should run next
          - modeling real world phenomena (lines show up in lots of places)
          - searching
       - 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)
          - isEmpty
       - how could we implement this?
          - Linked list
             - where should we add and remove items?
                - doesn't actually matter, but we do need a doubly linked list either way
                - we'll add them at the back and remove them from the front
             - look at LinkedQueue in StacksAndQueues code
             - runtime: assuming we use a doubly linked list
                - enqueue: O(1)
                - dequeue: O(1)
                - peek: O(1)
                - empty: 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 a the List interface, it makes a difference which underlying data structure we use... pick the right one!