CLRS 2.2 solutions

2.2-1

Express the function \(n^3 / 1000 - 100 n^2 - 100n + 3\) in terms of \(\Theta\)-notation.

Sol’n

\(n^3 / 1000 - 100 n^2 - 100n + 3 = \Theta(n^3).\)

2.2-2

Consider sorting \(n\) numbers stored in array \(A\) by first finding the smallest element of \(A\) and exchanging it with the element in \(A[1].\) Then find the second smallest element of \(A\), and exchange it with \(A[2].\) Continue in this manner for the first \(n - 1\) elements of \(A.\) Write pseudocode for this algorithm, which is known as selection sort. What loop invariant does this algorithm maintain? Why does it need to run for only the first \(n - 1\) elements, rather than for all \(n\) elements? Give the best-case and worst-case running times of selection sort in \(\Theta\)-notation.

Sol’n

for i = 1 to n - 1
    min_key = i
    for j = i + 1 to n
        if A[j] < A[min_key]
            min_key = j
    A[i], A[min_key] = A[min_key], A[i]

Proof of inner loop:

Inner loop claim:

The inner loop will update the var \(min\\_key\) to the minimum value of \(A[i..n].\)

Inner loop invariant:

At the beginning of each iteration of the loop, \(min \\_ key\) satisfies \(A[min\\_key] \le A[k]\) for \(i \le k < j\).

Initialization:

Indeed, we have \(j = i + 1\), thus \(i \le k < i + 1\), so \(k = i\). We also have \(min\\_key = i\) before the first iteration, so \(A[min\\_key] = A[i] = A[k].\)

Maintenance:

We fix \(j\), and assume \(A[min\\_key] \le A[k]\) for \(i \le k < j.\)

If \(A[j] < A[min\\_key],\) then we have a new \(min\\_key' = j,\) and we now have

\[ A[min\_key'] = A[j] < A[min\_key] \le A[k], \text{ for $i \le k < j.$} \]

The above equation gives us the desired statement,

\[ A[min\_key'] \le A[k], \text{ for $i \le k < j + 1.$} \]

We consider the other case, \(A[j] \not< A[min\\_key,\) that is, \(A[min\\_key] \le A[j],\) then we have immediately have the desired result,

\[ A[min\_key] \le A[k], \text{ for $i \le k < j + 1.$} \]

Termination:

As the loop terminates, we have \(j = n + 1.\) Then, the loop invariant gives that \(A[min\\_key] \le A[k],\) for \(i \le k < n + 1.\) Thus \(min\\_key\) is the index of the minimum value in \(A[i..n].\)

Proof of outer loop:

Loop invariant:

For each iteration of the for loop, \(A[1..i - 1]\) is sorted, and all elements there are smaller than any in \(A[i..n].\)

Initialization:

Trivially true for \(i = 1\), since \(A[1..i - 1] = A[1..0]\) is empty.

Maintenance:

We fix \(i\), assume \(A[1..i - 1],\) and that each are smaller than any of \(A[i..n].\)

After the body of the loop is executed, we will have a new \(A'[i..n]\) where \(A'[i]\) is smaller than any of \(A'[i + 1..n].\)

So for the next iteration, as desired, we will have \(A[1..i]\) sorted and each element less than any of \(A[i + 1..n].\)

Termination:

The loop terminates when \(i = n,\) and thus we have all \(A[1..n - 1]\) are sorted, and each are smaller than \(A[n]\), thus \(A[1..n]\) is sorted, as desired.

Running times

Best-case and worst-case running times are the same, \(\Theta(n^2).\)

2.2-3

Consider linear search again (see Exercise 2.1-3). How many elements of the input sequence need to be checked on the average, assuming that the element being searched for is equally likely to be any element in the array? How about in the worst case? What are the average-case and worst-case running times of linear search in \(\Theta\)-notation? Justify your answers.

Sol’n

1  for i = 1 to A.length
2      if A[i] = nu
3          return i
4      i = i + 1
5  return NIL

With equal likelihoods, the time to find \(\nu\) would be \(1, 2, \dots, n\), so expected value is

\[ \begin{align*} E[X] & = \sum x_ip_i \\ & = \left(\sum_{i=1}^n i\right)\cdot\left(\frac{1}{n}\right) \\ & = (1 + 2 + \cdots + n) / n \\ & = [n \cdot (n + 1) / 2] / n \\ & = (n + 1) / 2. \end{align*} \]

Worst-case is \(n.\) Both are \(\Theta(n).\)

2.2-4

TODO