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;
}