Announcements
 Welcome back at long last
 If only it were on more pleasant terms :\
 No quiz today since, well, last time was the exam :B
 Notes about project 3’s methods
isFullSolution
andreject
are what you should work on first those can be tested without doing anything else
 they’re subtly different though  be sure not to reject solutions with empty cells!
extend
should find the next available empty cell if all cells are full, it should return
null
 once it finds an empty cell, it should put a
1
there don’t forget to make a copy!
 make a method to copy a board.
 if all cells are full, it should return
next
should find the mostrecentlyplaced number and make it 1 bigger if the mostrecentlyplaced number was a 9, it should return
null
 if the mostrecentlyplaced number was a 1, it should make it a 2; 2 > 3; 3 > 4; etc.
 again, don’t forget to make a copy!
 if the mostrecentlyplaced number was a 9, it should return
 keeping track of which is the “mostrecentlyplaced” number can be tricky
 there are many ways to do it
 you are allowed to change the code (parameters to functions, etc)
 you’re not even required to store the board as an
int[][]
!
Ordering
 A total ordering is a mathematical concept
 Basically, it boils down to: “you can compare any two things; those two things will either be equal or one will come after the other; and comparison is transitive”
 Numbers have a total ordering
 You can pick any two numbers
 They will either be equal (3 = 3) or will come in one specific order (3 < 4, not 4 < 3)
 Comparison is transitive (3 < 4 and 4 < 5, so 3 < 5)
 Words have a total ordering, too
 Depending on the language, of course
 You can’t sort a collection of things that don’t have a total ordering!
 Or in Java parlance, you can’t sort a collection of things that don’t implement
Comparable
.
 Or in Java parlance, you can’t sort a collection of things that don’t implement
Sorting
 Unordered data is useful in a lot of cases, but many situations require ordered data
 Sorting is putting things in some kind of order
 Ordered data is easier to search through (remember binary search?)
 Ordered data is easier for people to look at
 Many algorithms  not just searching  require ordered data to work properly
 So lots of effort has gone into making good (efficient!) sorting algorithms.
 Automated sorting actually goes back to the 1800s (!)
 Punchcard sorters existed then and were used well into the 1960s and 1970s
 Early uses were for the census, taxes, and payroll
 An entire industry of “unit record equipment” did many of the things we use computers for today
 Think of them as “the greatgrandparent of spreadsheets and databases”
 A sorted array is such that:
 For all indices and , if , then .
 Don’t be fooled by the “lessthanorequals” sign  this works for more than just numbers
 And that could be a greaterthanorequals sign and still work just as well.
 Ascending order means that we start with the “smallest” value and go up
 Descending order means the opposite: start with the “biggest” value
 Duplicate items require some consideration…
 For simple things like numbers, duplicates are no issue
 But what about people’s names?
 If they have a family name and a given name…
 If you have 5 people with the same family name, what order should they go in?
 They’re not really duplicates…
 We’ll come back to this next time
Finding a minimum
 Maybe you’ve done this before (401? 0007?)
 This is sort of like a “running total” algorithm
 Keep a “smallest” value
 Loop over array and compare each against the smallest
 If the value in the array is smaller than the current smallest, it becomes the new “champion”
 How many steps does this take?
 iterations
 How many comparisons do we do?
 comparisons
 We can find any extremum (minimum, maximum, whatever) this way, and it’s always gonna be linear
Selection Sort
 We now know enough to make a simple sorting algorithm: selection sort.
 It’s called this because we select one item from the array, over and over.
 Let’s say I have this array:
 If I want to sort it in ascending order…
 Which item do I want to select to be the first item in the array?
 The smallest. The minimum.
 So, 1.
 Let’s make a second array that contains the sorted items:
 And let’s remove 1 from the original array:
 Now we just repeat the process.
 Select the smallest (minimum).
 Remove it from the original array.

Put it at the end of the new array.
 How much space do we need for each step?
 Well the unsorted array is getting 1 smaller, and the sorted array is getting 1 bigger…
 The space is constant.
 So it seems silly to need 2 arrays.
 Let’s make it work inplace  no second array needed.
 For
i = 0; i < n; i++
 Select the smallest (minimum), starting at item
i
. 
Swap it with item
i
.
 Select the smallest (minimum), starting at item
 This way lends itself to being written recursively very easily.
 Find minimum of
array[i to end]
 Swap minimum with
array[i]
 Recurse with
i + 1
 Find minimum of
 For
 What is the runtime?
 How many times does the outer loop run?
 How long does it take to find the minimum?
 How long does it take to swap two items?
 If we multiply all those together, it’s
 How many comparisons do we do?
 again, since we do comparisons to find the minimum on each of iterations
Bubble sort
 Here’s another simple algorithm
 We look for inversions: when a pair of items are in the wrong order.
 So, if we saw
5, 3
, that’s an inversion  cause 5 should come after 3.
 So, if we saw
 So here’s the algorithm:
 For
i = 0; i < n  1; i ++
 If
A[i]
>A[i + 1]
… Swap them, and set
i = 0
. (start over!)
 Swap them, and set
 If
 When this loop exits, no inversions have been found, and the array is sorted.
 For

Seems kind of silly, but it does work:
 Notice how sometimes numbers will move backwards through the array
 This is why it’s called bubble sort  the values sort of “bubble” through the array slowly
 It doesn’t go strictly beginningtoend like selection sort.
 And the values don’t end up in their final positions when we move them.
 What is the runtime?
 This is a little trickier, since the loop kind of starts over again and again
 But if we think about it in the worst possible case…
 We would find an inversion at
i == 0
 Then at
i == 1
 Then at
i == 2
…  And each time, we would have to look at
i + 1
items  Until
i = n
 We would find an inversion at
 It’s that sort of “triangular” behavior we saw before: again!
 You can also think of it like: each number in the array might need to move positions down, and there are numbers
 How many comparisons?
 Again, it’s gonna be
 Cause each of those numbers will have to move positions, requiring the same number of comparisons
Insertion sort
 Let’s (try to) do better.
 Insertion sort is a bit like a combination between selection and bubble sort.
 Like selection sort, we will have a “sorted part” of the array.
 Like bubble sort, we will “slide” items around.
 Here’s the algorithm:
 Pick the first item from the “unsorted” part of the array.
 Insert that item into the “sorted” part in the correct order.

We “slide” it into place righttoleft, kinda like bubble sort.

 Think of it like picking books off a shelf, and sliding them into place in the right order
 What is the runtime?
 It takes time to “slide” each number into place
 Therefore it’s still …
 Aaargh!!!
 How many comparisons?
 Again, for each item, since it might have to be compared to every item to its left
 So overall…
 Just as a brain teaser: how could we find where to put the item in the sorted part faster?
 We could use binary search
 That lets us find the right location in time…
 But it still takes time to move the items after it over. So we haven’t improved things significantly.
This is frustrating
 It feels like we should be able to do better, somehow.
 Well, we can.
 Next time we’ll look at three new sorting algorithms
 Two of them will be faster in general..
 And one will be faster in a totally different way!