2-1:

2-2:

a) loop invariant, initial condition, termination condition.

b) A[j] is the smallest element in A[j .. length[A]].

    initialization:

      at the start of the loop, j = length[A]. It's the smallest element in

      A[length[A] ~ length[A]] (because it's the only element).

    maintenance:

      if j = k is the smallest element in A[j .. length[A]], then in the for

      loop, it would compare A[k-1] and A[k], and swap them if A[k-1] is

      larger. This ensures that A[j] is the smallest element when j = k-1.

    termination:

      when j = i+1, it terminates, and A[i+1] is the smallest element in

      A[i+1 ~ length[A]], according to the maintenance proved.

c) A[1 .. i] is sorted, and A[i+1] is the next smallest element in

   A[i+1 .. length[A]] (proved in b)).

    initialization:

      at the start, i = 1. It's the only element in A[1 .. i] thus it's

      sorted.

    maintenance:

      if i = k, and A[1 .. k] is sorted; the next intake element is the

      smallest in the rest of the array, while the largest in A[1 .. i].

      Therefore, A[1 .. k+1] is sorted.

    termination:

      it terminates at i = length[A]. the loop invariant maintains.

d) the worst-case running time is O(n^2). It's the same as insertion sort.

    However, the constant factor of bubble sort may be larger than insertion

    sort, because it has to go through every element in the for loop; while

    insertion sort only need to check until a proper place is found.

2-3:

Reference: http://answers-by-me.blogspot.com/2010/07/clrs-2e-problem-2-3.html

a) O(n)

b) pseudo code:

double sum = 0;
for(int i=0; i<= n; i++){
sum
+= A[i] * pow(x,i);
}
return sum;

// the running time of this algorithm would depends on how fast the computer can compute pow(x,i); suppose T(pow(x,i)) = O(k), then T = O(nk).

c)

d) based on c, we can see that when it terminates, it would evaluate the polynomial characterized by the coefficients a0,a1,..,an.

2-4:

a) (1,5), (2,5), (3,5), (4,5), (3,4)

b) 1 + 2 + … + n-1 = n(n-1)/2

c) equal. Cuz one inversion in the array means one swap during the insertion sort, and the constraint in inversion sort is the number of swaps it has to do.

d)

/* @params:
* A: an array to be counted
* s: the start index of that array
* e: the end index of that array
* @return:
* the number of inversions this part of the array has.
* @side-effect:
* this algorithm would also sort the array using merge sort
*/

int MergeCount(array A, int s, int e){

// super divided; merge
if(e <= s+1){
if(A[s] < A[e]){
swap(A,s,e);
return 1;
}
else{
return 0;
}
}

int mid = (s + e)/2;
int res = 0;
res
+= MergeCount(A,s,mid);
res
+= MergeCount(A,mid+1,e);

// then merge
int size = (e - s + 1);
int B[size]; // create a new array to copy elements in, for merge
for(int i=0;i<size;i++){
B[i]
= A[s+i];
}
int i = 0, j = mid - s + 1; t = s;
while(i <= mid - s && j <= e){
if(B[i]>=B[j]){
A[t
++] = B[j++];
res
+= (mid - s + 1);
}
else(B[i] < B[j]){
A[t
++] = B[i++];
}
}
if(i>mid-s){
while(j<=e) A[t++] = B[j++];
}
else{
while(i<= mid-s) A[t++] = B[i++];
}
return res;
}