CS 411 Fall 2025 > Outline & Supplemental Notes for September 17, 2025
CS 411 Fall 2025
Outline & Supplemental Notes
for September 17, 2025
Outline
Decrease and Conquer [L Ch 4 intro]
- What it is
- Algorithmic strategy: use relationship between solution to instance of problem and solution to smaller instance of same problem.
- Can be top-down or bottom-up.
- Variations
- Three categories of Decrease and Conquer algorithms
- Decrease by a constant.
- Decrease by a constant factor.
- Decrease by variable amount.
- Analysis
- Three categories of Decrease and Conquer algorithms
Insertion Sort [L 4.1]
- How it works
- Code
- Nonrecursive implementation.
- Recursive implementation.
- Analysis
- What Insertion Sort does well (see Supplemental Notes)
Example code:
insertion_sort.cpp
.
Supplemental Notes
What Insertion Sort does Well
Nearly Sorted Data
There are two kinds of lists we can call nearly sorted:
- Lists in which each item is near the location it would be in if the list were sorted.
- Lists in which few items are out of order.
Above, “near” and “few“ are ways of saying \(O(1)\). In type 1, we want each item to be at most some constant distance away from its sorted location. In type 2, we want at most some constant number of items to be out of order.
When Bubble Sort is Fast
We saw that an optimized Bubble Sort is linear-time for type 1 nearly sorted data. Each pass moves items closer to their final spots. Thus we can sort the list in a fixed number of passes; an optimized Bubble Sort will quit at this point.
Bubble Sort is not linear time for type 2 data. To see this, move the smallest item in a list to the end. Each Bubble Sort pass moves it back by 1. So all the passes need to be done.
When Insertion Sort is Fast
Insertion Sort is linear-time for both kinds of nearly sorted data. In type 1, the search and the rotate will only need to move a small number of items (again, “small” means \(O(1)\)). Our outer loop runs to completion, but each iteration only requires constant time.
In type 2, most items are already in the proper place; they do not need to be moved. Some small number of items need to be moved; the iterations for these are linear-time. So we have a fixed number of linear-time iterations: linear time in all.
Insertion Sort is also generally held to be very fast for small lists. This is a fuzzy statement; its truth depends on what is sorted, what is meant by “small”, what computing architecture is used, etc. It is simply the experience of a large number of people.
Insertion Sort in Practice
The two cases mentioned above—nearly sorted lists and small lists—account for most of the practical applications of Insertion Sort: it is used as part of other algorithms.
In particular, we can modify any of the sorting algorithms in the Quicksort family so that, if a recursive call is made to sort a small sublist, then the call does nothing. With this modification, the output of the algorithm is a nearly sorted list. We can then finish sorting by doing an Insertion Sort.
Another use of Insertion Sort is as a way of handling all the sorting when the list to be sorted is small. Some sorting-algorithm implementations will switch to Insertion Sort when the size of the input list is below some threshold.
A check of the C++ Standard Library distributed
with a recent version of g++ determined that
both of the above are done.
The Quicksort optimization using a final Insertion Sort is used
in the implementation of std::sort
,
and the switch to Insertion Sort for small lists
is used in
the implementation of std::stable_sort
.