WEEK10: sorting (and more analysis of algorithms) --------------------------------------------------------------- W: selection sort analysis REVIEW: - look at http://www.youtube.com/watch?v=INHF_5RIxTE for a fun review of insertion, selection, and bubble sort - see http://www.sorting-algorithms.com for another comparison of the sorts SORTING: - see /home/jk/inclass/sorts.examples for a review of the three sorts we talked about last time (selection sort, insertion sort, and bubble sort) - can you write a working selection sort function??? ----------------------------------------------------- find smallest in a list algorithm... ismall = 0 for i in range(0, len(L)): if L[i] < L[ismall]: ismall = i L[0],L[ismall] = L[ismall],L[0] - this does the selection sort algorithm for just the first (0th) element in the list. We need to do the above for all indecies 0 --> len(L) ----------------------------------------------------- selection sort algorithm: - find smallest in list, move to index 0 - find smallest in rest of list, move to index 1 - find smallest in rest of list, move to index 2 ...and so on ----------------------------------------------------- - here's one version of selection sort: # ------------------------------------------------------ # def selectionSort(L): """ sort list in place using selection sort algorithm """ for i in range(len(L)): ismall = i # find index of smallest element of rest of list for j in range(i+1,len(L),1): if L[j] < L[ismall]: ismall = j # swap smallest element with L[i] L[i],L[ismall] = L[ismall],L[i] # ------------------------------------------------------ # - how does selection sort compare to python's built-in sort? - copy over timeSorts.py and add your selectionSort - run timeSorts.py and test your sort with small values of N - once you know it works, test it with N=1000,2000,4000 to see how the times change for larger N's N = 1000 selection sort time: 0.1685 N = 1000 built-in sort time: 0.0003 N = 2000 selection sort time: 0.4269 N = 2000 built-in sort time: 0.0007 N = 4000 selection sort time: 1.6595 N = 4000 built-in sort time: 0.0015 *** clearly L.sort() is faster...why?? - how does selection sort's time depend on the size of the list (N)? ANALYSIS: - how many "steps" does selection sort require to sort a list? for i in range(len(L)): <--- for loop depends on N ismall = i # find index of smallest element of rest of list for j in range(i+1,len(L),1): <--- another (nested) for loop if L[j] < L[ismall]: ismall = j # swap smallest element with L[i] L[i],L[ismall] = L[ismall],L[i] Here's how selection sort works on a sample list of length 7: [ 9, 50, -2, 6, 9, 17, 20] <-- find smallest num, swap to position 0 --> [ -2, 50, 9, 6, 9, 17, 20] <-- find smallest, swap to pos 1 --> [ -2, 6, 9, 50, 9, 17, 20] <-- find small, swap to 2 --> [ -2, 6, 9, 50, 9, 17, 20] <-- find/swap to 3 --> [ -2, 6, 9, 9, 50, 17, 20] <-- swap to 4 --> [ -2, 6, 9, 9, 17, 50, 20] <-- 5 --> [ -2, 6, 9, 9, 17, 20, 50] <-> [ -2, 6, 9, 9, 17, 20, 50] See how that looks like an NxN matrix? Actually, it looks like 0.5*(NxN), but that's still proportional to N-squared!! YOUR TURN: - something proportional to N-squared is called quadratic, because if you double N, the "something" quadruples! - run the pylabLinePlots.py program again to see the comparison of things proportional to N (linear) vs NlogN vs N-squared (quad) MERGE SORT: - see http://www.sorting-algorithms.com to compare sorts - do interactive demo with cards and students! - merge sort uses a divide-and-conquer method to sort a list: given a list, split it in two (if the size of the list > 1) sort each of the two halves of the list merge the two sorted halves back into the original list - the second step above (sort each of the two halves) can actually be done by calling a new mergeSort function Note: this is recursion...a function that calls itself to get it's work done
Here are some interesting merge sort links: