Question 1:
Question 2: Using binary search to find the right place to insert the next item would (usually) speed up the sort but it would not change the complexity, which would still be O(N2) in the worst case, since in the worst case (when the item needs to be inserted at the very beginning of the array each time) it is necessary to move O(N2) values.
while ((left <= mid) && (right <= high)) { // choose the smaller of the two values "pointed to" by left, right // copy that value into tmp[pos] // increment either left or right as appropriate // increment pos if (A[left].compareTo(A[right] <= 0) { tmp[pos] = A[left]; left++; } else { tmp[pos] = A[right]; right++; } pos++; } // when one of the two sorted halves has "run out" of values, but // there are still some in the other half; copy all the remaining // values to tmp // Note: only 1 of the next 2 loops will actually execute while (left <= mid) { tmp[pos] = A[left]; left++; pos++; } while (right <= high) { tmp[pos] = A[right]; right++; pos++; }
When the array is already sorted, merge sort still takes O(N log N) time because it still makes the same recursive calls and still goes through both half-size arrays to merge the values.
When the array is already sorted, quick sort takes O(N log N) time, assuming that the "median-of-three" method is used to choose the pivot. This is because the pivot will always be the median value, so the two recursive calls will be made using arrays of half size and so the calls will form a balanced binary tree as illustrated in the notes.