Homework 1 and insertion sort
Logistics
The weekly rhythm of the class will be: drill due Monday, homework/project due Tuesday, homework out on Wednesday, labs Thursday/Friday (lab signups are posted now!).
There’s a calendar on the website that shows TA hours and my office hours. The TAs are excited to help out with homeworks, projects, labs, etc. Feel free to stop by my office hours even if you don’t have a specific question–I’m happy to chat about computer science, career advice, etc. I keep vegan and gluten-free snacks in my office, and I’m also available by appointment.
This class will not have a written final exam, but we will have:
- 3 in-class quizzes (see the course website for the schedule)
- An independent final project
What you work on for your final project is up to you. The ideal project is something you’re interested in and excited about that also demonstrates that you can apply some of the concepts we’ll learn about in this course. We’ll also post some suggestions for project ideas in a month or so.
Homework 1
We discussed how to get started on Homework 1. See the lecture capture for details.
Insertion sort revisited
Last time, we ended up with this pseudocode description of insertion sort:
index = 1 while index < length of list: element = list[index] if element < list[index-1]: put element in the right place index = index + 1
This is pretty high-level, but we can already start to analyze it a bit. For instance: can we figure out how fast it runs?
The `index` variable is going from `1` to whatever the length of the list is. So, whatever’s inside that “while” is going to happen once for every element in the list besides the first one. How long do the operations inside the “while” block take? Do any of them depend on how much data we’re looking at?
That “put element in the right place” line stands out–it’s hard to say how long that’s going to take unless we see more. Before we elaborate on what that might look like: are there lists where we’ll never have to move an element to the right place? What if a list is already sorted?
So, even from this very high-level description, we know something about this algorithm: on a list that’s already sorted, it will run in linear time (i.e., it does a constant amount of work for every element in the list).
We’ll learn about other sorting algorithms later in the class that have better performance in general, but this property–that insertion sort runs in linear time on sorted lists–turns out to be very useful. It’s so useful, in fact, that the built-in Python sorting algorithm uses insertion sort for short lists.
Now, back to that “put element in the right place” line. Can we elaborate on that? How do we go about putting the element where it goes? Here’s an attempt:
index = 1 while index < length of list: element = list[index] if element < list[index-1]: insertion-index = index while list[insertion-index] < list[insertion-index - 1]: swap list[insertion-index] and list[insertion-index - 1] insertion-index = insertion-index - 1 index = index - 1
We can simplify this a bit: since we have the “while” now, we don’t need the “if”.
index = 1 while index < length of list: element = list[index] insertion-index = index while list[insertion-index] < list[insertion-index - 1]: swap list[insertion-index] and list[insertion-index - 1] insertion-index = insertion-index - 1 index = index - 1
And we don’t need “element” either:
index = 1 while index < length of list: insertion-index = index while list[insertion-index] < list[insertion-index - 1]: swap list[insertion-index] and list[insertion-index - 1] insertion-index = insertion-index - 1 index = index - 1
Now that we’ve defined in more detail what we mean to put a list element where it goes, we can think a bit more about it’s runtime. So: what’s the runtime of insertion sort?
The answer is that it depends on the input list! As we’ve already seen, for sorted input lists, insertion sort runs in linear time. Since that’s the best case for this algorithm (why?), we’ll call linear time the “best-case runtime” for this algorithm. What’s the worst case? Well, if the list is sorted in reverse order, the algorithm will have to drag every element all the way back to the front of the list. How many operations is that? Let’s look at a list like `[5, 4, 3, 2, 1]`. Dragging those elements back takes `1 + 2 + 3 + 4` operations; as we saw in CSCI 0111, this indicates a quadratic runtime. So in the worst case, insertion sort runs in quadratic time.
So it seems roughly like insertion sort runs slower the “less sorted” a list is. It’s a bit tricky to define the “average” case here–it depends how sorted your data is!–but on randomly-ordered lists, insertion sort also runs in quadratic time.