CS241: Spring 2017 -- Lecture 17, what could go wrong? Why is this "so-called" O(nlogn) algorithm empirically O(n^2)?

  1. Printing values for N, NlogN, and N^2 in a nicely formatted table
  2. Write a method which is passed an int[] list, and two indices, firstI, and lastI; it should reverse all the values between firstI and lastI, inclusive. E.g. if the initial list were: 1, 2, 3, 4, 5, 6; firstI=2, lastI=4, the result should be: 1, 2, 5, 4, 3, 6
  3. Ways to make sorts n^2
    1. Why is the MergeSort in examples from class O(n^2)?
    2. Quick sort on a sorted list, or... a long list where every value is between 0-100...
    3. Tree sort on a sorted list - what is a completely degenerate binary tree called? A list!
    4. Radix sort if either enqueue and dequeue is O(n)!
  4. Solutions to the above
    1. No shift! Use a work array; allocate it once, out of the recursion, initialize it by copying from the list you are sorting at the top of mergeSort, and emit from merge directly to the list you are sorting
    2. Randomize first. If there are only 100 values, use counting sort instead.
    3. Use a tree structure that is certain to be balanced. A heap is a famous one.
    4. Modify enqueue (or dequeue) so it is O(1).
  5. Heaps - a solution to the worst case of a BST
    1. always has a near-delta shape (no degeneracy!)
    2. every root is <= both children's roots, thus the smallest element is at the root
    3. Application: CPU queue
  6. Heap methods
    1. insert
      	insert new element at the insertion point (first empty slot, to the right of the step on the near-delta)
      	swap up to it's proper place (to preserve heapness)
      	i.e.
      	if ! at root of heap
      		if it is < its parent (i.e. is out of place) {
      			swap roots with parent
      			recurse on parent
      		}	    	
                      
      running time?
    2. delete root
      	save the root (to return)
      	swap from rightmost, bottom row (to the left of the step on the near-delta) and trim the old root
      	swap the root down to the proper place
      	i.e.
      	if ! a leaf
      		if it is > either child (or just the left, if there's no right) {
      			swap roots with smaller child
      			recurse on that child
      		}	    	
                      
      running time?
  7. representation; an array!
  8. heapsort
    	for each element in the list
    		insert in the heap
    	list.clear();
    	while !heap.isEmpty()
    		list.add(heap.deleteRoot());