I see that no one has mentioned introsort, which solves quick sort's O(n^2)
worst case by switching to heapsort when the recursion depth exceeds a certain threshold. This means that quick sort will not get the chance to degenerate, since its number of recursive calls will definitely be limited.
Another optimization is to switch to insertion sort whenever the number of elements of the sequence you are currently at is small (say 16).
This is how introsort could look:
void Introsort(int A[], int N, int left, int right, int depth)
{
if ( left < right ) // note: this doesn't switch to insertion sort if right - left is small enough
{
if ( (1 << depth) > N )
Heapsort(A, left, right);
else
{
int P = Partition(A, left, right);
Introsort(A, N, left, P, depth+1);
Introsort(A, N, P+1, right, depth+1);
}
}
}
This, combined with a good partition function (simply randomly choosing the pivot should be good enough for most purposes), will give you a very fast sorting algorithm.
There is also the choice of radix sort, which works really well, especially if your floats are not too big. From what I've seen though, it takes millions of elements for radix sort to outperform introsort.