CavarrettaSort(A[0 .. n - 1]):
if n = 2 and A[0] > A[1]
swap A[0] and A[1]
else if n > 2
m = ceiling(2n/3)
CavarrettaSort(A[0 .. (m - 1)])
CavarrettaSort(A[(n - m) .. (n - 1)])
CavarrettaSort(A[0 .. (m - 1)])
Base case: If n = 2, the two elements of the list are swapped if out of order, resulting a correctly sorted list.
Suppose as inductive hypothesis that CavarrettaSort(A[0 .. k-1])
correctly sorts its input array for all \(k<n\).
Then CavarrettaSort(A[0...n-1])
takes the following steps: 1. Correctly sorts the first 2/3 of the array, according to the inductive hypothesis 2. Correctly sorts the last 2/3 of the array, according to the inductive hypothesis 3. Correctly sorts the first 2/3 of the array again, according to the inductive hypothesis.
After step 2, the last 1/3 of the array will contain the highest 1/3 of numbers, because any of these numbers that may have been in the first 1/3 were moved into the middle 1/3 in step 1, and the last 1/3 in step 2. After step 3, the first 2/3 of the array will be sorted correctly as well, because all numbers in the first 2/3 at this point are less than all numbers in the last 1/3, resulting in a complete solution.
First, since \(m\) is the ceiling of \(2n/3\), \(n-m\) is never larger than \(2m-n\).
After the first CavarrettaSort(A[0 .. (m - 1)])
call, all of the \(n-m\) elements of A[(2m-n)..(m-1)]
(the second “1/3”) are greater than all of the \(2m-n\) elements of A[0..(2m-n-1)]
(the first “1/3”), by inductive hypothesis. Therefore, none of the largest \(n-m\) elements of the entire array can be in A[0..(n-m-1)]
, and so the largest \(n-m\) elements must be in A[(n-m)..(n-1)]
(the last “2/3”).
After the call CavarrettaSort(A[(n - m) .. (n - 1)])
, these largest \(n-m\) elements must be in order in A[m..(n-1)]
(the last “1/3”), by inductive hypothesis. The final recursive call puts the smallest \(m\) elements of the array in order in A[0..(m-1)]
, by inductive hypothesis. Therefore, the entire array is correctly sorted.
CavarrettaSort(A[0 .. n - 1]):
if n = 2 and A[0] > A[1]
swap A[0] and A[1]
else if n > 2
m = ceiling(2n/3)
CavarrettaSort(A[0 .. (m - 1)])
CavarrettaSort(A[(n - m) .. (n - 1)])
CavarrettaSort(A[0 .. (m - 1)])
\[ C(n) = \left\{\begin{array}{lr} 1, & \text{for } n=2,\\ 3C\left(\left\lceil\frac{2}{3}n\right\rceil\right), & \text{for } n>2.\\ \end{array}\right. \]
Ignoring the ceiling,
\[\begin{align} C(n) &= 3C\left(\frac{2}{3}n\right) = 3^2C\left(\left(\frac{2}{3}\right)^2n\right) = 3^3C\left(\left(\frac{2}{3}\right)^3n\right) \\ & = \cdots = 3^LC\left(\left(\frac{2}{3}\right)^Ln\right) = 3^L C(2) = 3^L \cdot 1 = 3^L \end{align}\]
Where \(\left(\frac{2}{3}\right)^Ln = 2\). Solving for \(n\) gives \(L = \log_{1.5}(n/2)\).
Therefore, \(C(n) = 3^{\log_{1.5}(n/2)} = (n/2)^{\log_{1.5} 3} \in O(n^{\log_{1.5} 3}) = O(n^{2.7095\ldots})\)
\[ C(n) = \left\{\begin{array}{ll} 0 & \mbox{if } n=1 \\ 2C(n/2) + O(n) & \mbox{if } n>1 \end{array} \right. \]
Total up each level in the recursion tree:
level total
n n
/ \
n/2 n/2 n
/ \ / \
n/4 n/4 n/4 n/4 n
/ \ / \ / \ / \
n/8 n/8 n/8 n/8 n/8 n/8 n/8 n/8 n
... and so on
There are \(\log n\) levels in this tree, so \(C(n) \in O(n \log n)\).
\[ T(n) = \left\{\begin{array}{ll} \mbox{doesn't matter} & \mbox{if } n \leq n_0 \\ rT(n/c) + O(f(n)) & \mbox{if } n > n_0 \end{array} \right. \] Recursion tree:
See Figure 1.9.
Recursive case of divide and conquer recurrence:
\[ T(n) = rT(n/c) + O(f(n)) \]
[CLRS] calls this the Master Theorem for solving d&c recurrences.
Table #1 | Table #2 | Table #3 | Table #4 | Table #5 | Table #6 | Table #7 |
---|---|---|---|---|---|---|
Claire | Grace | Blake | Jack | Bri | Kevin | Nathan |
Andrew | Kristen | Talia | Drake | Logan | James | John |
Josiah | Ethan | Levi | Jordan | Isaac | Trevor | Graham |
Draw a recursion tree for the recurrence \(F(n) = 3F(n/4) + O(\sqrt{n})\).
Write down the first four terms in the sequence of row sums.
Apply the Master Theorem to solve the recurrence.
\[ C(n) = \left\{\begin{array}{lr} 1, & \text{for } n=2,\\ 3C\left(\left\lceil\frac{2}{3}n\right\rceil\right) + K, & \text{for } n>2.\\ \end{array}\right. \]
Use a recursion tree (with root \(K\)) to solve this recurrence. What effect did adding the constant term have?