### CS51 - Spring 2010 - Lecture 26

• course reviews

- put up practice final
- our final time slot is Monday, May 10 at 2:00pm
- TP2 is due last day of class at 5pm

• "For me, great algorithms are the poetry of computation. Just like verse, they can be terse, allusive, dense and even mysterious. But once unlocked, they cast a brilliant new light on some aspect of computing.'' -- Francis Sullivan

• What is an algorithm?
- way for solving a problem
- method of steps to accomplish a task

• Examples
- sort a list of numbers
- find a route from one place to another (cars, packet routing, phone routing, ...)
- find the longest common substring between two strings
- microchip wiring/design (VLSI)
- solving sudoku
- cryptography
- compression (file, audio, video)
- spell checking
- pagerank
- classify a web page
- ...

• Main parts to algorithm analysis
- developing algorithms that work
- making them faster
- analyzing/understanding the efficiency/run-time

• Sorting
Input: An array of numbers nums
Output: The array of numbers in sorted order, i.e. nums[i] <= nums[j] for all i < j

- cards
- sort cards: all cards in view
- sort cards: only view one card at a time

- look at Sort code
- Selection sort
- How many operations does the algorithm take? How long will it take? How efficient is it?
- what counts as an operation?
- Different operations take different amounts of time. Even from run to run, things such as caching, etc. will complicate things
- will depend on the input
- We want a tool to allow us to talk about and compare different algorithms while hiding the details that don't matter
- asymptotic analysis
- Key idea: how does the run-time grow as we increase the input size?
- in our case, as we sort more numbers, roughly how will the run-time increase
- for example, if we double the number of numbers we're sorting, what will happen to the run-time?
- unchanged?
- double?
- triple?
- Compare different algorithms
- f1(n) takes n^2 steps
- f2(n) takes 2n + 100 steps
- f3(n) takes 4n + 1 steps
- Which algorithm is better? Is the difference between f2 and f3 impor-
tant/signicant?

- Big-O notation: an upper bound on the function/run-time
- Gives us the big picture, without worrying about details
- Given a function/method how will it grow? linearly? quadratically?
- Examples:
- n^2 is O(n^2)
- n^2 + n + 200 is O(n^2)
- 5n + 10 is O(n)
- ...

- runtimes table
- this gives us groups of methods/functions that behave similarly

- What is the running time of selection sort?
- We'll use the variable n to describe the length of the array/input
- How many times do we go through the for loop in selectionSort?
- n times
- Each time through the for loop in selectionSort, we call indexOfSmallest. How many times do we go through the for loop in indexOfSmallest?

- end_index - start_index + 1
- first time, n-1, second, n-2, third, n-3 ...
- O(n)
- what is the overall cost for selectionSort?
- we go through the for loop n times
- each time we go through the for loop we incur a cost of roughly n
- O(n^2)

- Insertion sort
- what is the running time?
- How many times do we iterate through the while loop?
- in the best case: no times
- when does this happen?
- what is the running time? linear, O(n)
- in the worst case: j - 1 times
- when does this happen?
- what is the running time?
- \sum_{j=1}^n-1 j = ((n-1)n)/2
- O(n^2)
- average case: (j-1)/2 times
- O(n^2)

- Merge sort
- first, look at the merge method
- how can we use this method to sort numbers?
- how could we use this method to sort two numbers?
- can we repeat this idea? - what is the runtime?
- what is the runtime?
- look at the layers
- each layer processes n items
- how many layers are there?
- each time we split the data in half
- 2^i = n
- log(n) levels
- O( n log n )

• Built-in sorting
- Arrays.sort(Object[] a) -- uses merge sort
- Collections.sort(List list) -- uses quicksort