CmSc 250 Intro to Algorithms
Sorting Algorithms
Insertion Sort
Simple sorting algorithms : O(N2)
Shellsort: o(N2)
Advanced sorting algorithms: O(NlogN)
In general: Ω(NlogN)
PRE: array of N elements (from 0 to N-1)
POST: array sorted
For j = p to N-1
Take the j-th element and find a place for it among
the first j sorted elements
int j, p;
comparable tmp;
for ( p = 1; p < N ; p++)
{
tmp = a[p];
for (j = p; j > 0 && tmp < a[j-1]; j--)
a[j] = a[j-1];
a[j] = tmp;
}
To insert the last element we need at most N-1 comparisons
and N-1 movements.
To insert the N-1st element we need
N-2 comparisons and N-2 movements.
….
To insert the 2nd element we need 1 comparison and one movement.
To sum up:
2* (1 + 2 + 3 +… N - 1) = 2 * (N - 1)* N / 2 = (N-1)*N = Θ (N2)
If the greater part of the array is sorted,
the complexity is almost O(N)
The average complexity is
proved to be = Θ (N2)
Simple sorting algorithms swap elements that
are not ordered.
Swapping is done by bubble sort, and by insertion sort.
Thus the complexity depends on the number of swaps.
To estimate how many swaps are needed on average, we define inversion in the following way:
Definition: An inversion is an ordered pair (Ai, Aj) such that i < j but Ai > Aj.
Example: 10, 6, 7, 15, 3, 1
Inversions are:
( 10, 6 ), ( 10, 7 ), ( 10, 3 ), ( 10, 1 )
( 6, 3 ), ( 6, 1 )
( 7, 3 ), ( 7, 1 )
( 15, 3 ), ( 15, 1 )
( 3, 1 )
The following is true:
How many inversions are there in an average unsorted array?
In general this is a tricky question to answer - just
what is meant by average?
However, we can make a couple
of simplifying assumptions:
Under these circumstances we can say the following:
Theorem 1 [Average number of inversions]
The average number of inversions in an array of N
distinct elements is N (N - 1) / 4
Proof:
Thus A has N (N - 1) / 4 inversions.
Consequently the insertion sort has an average running time
of O(N2).
In fact we can generalize this result to all sorting algorithms
that work by exchanging adjacent elements to eliminate inversions.
Theorem 2 Any algorithm that sorts by exchanging adjacent elements requires Ω (N2) time on average.
The proof follows immediately from the fact that the average
number of
inversions is N(N-1)/4: each adjacent swap
removes only one inversion,
so
Ω(N2)
swaps are required.
Theorem 2 above implies that for a sorting algorithm to run
in less than quadratic time
it must do something other than swap adjacent elements.
Learning Goals
Exam-like questions