Quicksort has a truly dreadful worst-case performance, as you have discovered here. It is calling itself at a stack depth of 5000. This Wikipedia article has a good discussion on the subject. In particular, it mentions tail recursion as a solution to your stack overflow problem.
Briefly, this means that instead of the last call to quicksortLastElementPivot
, followed immediately by a return, you just loop back to the start of the function. This has the same effect, but the tail recursion doesn't increase the stack size. For this to work, you have to make sure that the smaller of the two partitions is sorted first, using traditional recursion, and the larger partition is sorted by tail recursion. Something like this (not tested!):
void quicksortLastElementPivot(int*arr, int lo, int hi)
{
TailRecurse:
if (lo<hi)
{
int mid = partition_lastElementPivot(arr, lo, hi);
if (mid < (lo + hi) / 2)
{ // First partition is smaller
quicksortLastElementPivot(arr, lo, mid - 1); // Sort first partition
lo = mid + 1; goto TailRecurse; // Sort second partition
}
else
{ // Second partition is smaller
quicksortLastElementPivot(arr, mid + 1, hi); // Sort second partition
hi = mid - 1; goto TailRecurse; // Sort first partition
}
}
}