问题
Following is my insertion sort code:
void InsertionSort(vector<int> & ioList)
{
int n = ioList.size();
for (int i = 1 ; i < n ; ++i)
{
for (int j = 0 ; j <= i ; ++j)
{
//Shift elements if needed(insert at correct loc)
if (ioList[j] > ioList[i])
{
int temp = ioList[j];
ioList[j] = ioList[i];
ioList[i] = temp;
}
}
}
}
The average complexity of the algorithm is O(n^2).
From my understanding of big O notation, this is because we run two loops in this case(outer one n-1 times and inner one 1,2,...n-1 = n(n-1)/2 times and thus the resulting asymptomatic complexity of the algorithm is O(n^2).
Now I have read that best case is the case when the input array is already sorted. And the big O complexity of the algorithm is O(n) in such a case. But I fail to understand how this is possible as in both cases (average and best case) we have to run the loops the same number of times and have to compare the elements. The only thing that is avoided is the shifting of elements.
So does complexity calculation also involve a component of this swapping operation?
回答1:
Yes, this is because your implementation is incorrect. The inner loop should count backward from i-1
down to 0
, and it should terminate as soon as it finds an element ioList[j]
that is already smaller than ioList[i]
.
It is because of that termination criterion that the algorithm performs in O(n) time in the best case:
If the input list is already sorted, the inner loop will terminate immediately for any i
, i.e. the number of computational steps performed ends up being proportional to the number of times the outer loop is performed, i.e. O(n).
回答2:
Your implementation of "insertion sort" is poor.
In your inner loop, you should not scan all the way up to i-1
swapping each element greater than ioList[i]
. Instead, you should scan backwards from i-1
until you find the correct place to insert the new element (that is, until you find an element less than or equal to the new element), and insert it there. If the input is already sorted, then the correct insertion point is always found immediately, and so the inner loop does not execute i-1
times, it only executes once.
Your sort is also worse than insertion sort on average, since you always do i+1
operations for each iteration of the outer loop -- some of those ops are just a comparison, and some are a comparison followed by a swap. An insertion sort only needs to do on average half that, since for random/average input, the correct insertion point is half way through the initial sorted segment. It's also possible to avoid swaps, so that each operation is a comparison plus a copy.
来源:https://stackoverflow.com/questions/13229229/why-is-insertion-sort-best-case-big-o-complexity-on