Если вам нужно отсортировать большие массивы и беспокоиться о шаблонах данных в худшем случае, вызывающих переполнение стека, быстрая сортировка может выполнить рекурсию на меньшем разделе и вернуться к началу для большего раздела, что позволит избежать переполнения стека, но сложность времени в худшем случае будетвсе еще быть O (n ^ 2).
void Quick_Sort(const void* ptr, int low, int high, size_t size, int (*cmp)(const void*, const void*))
{
int i;
int j;
char *pivot;
while(low < high){
i = low;
j = high;
pivot = (char*)ptr + ((low+high)/2) * size;
while (i <= j)
{
while (cmp((char*)ptr + i * size, pivot) == -1)
i++;
while (cmp((char*)ptr + j * size, pivot) == 1)
j--;
if (i <= j) {
Swapper((char*)ptr + i * size, (char*)ptr + j * size, size);
i++;
j--;
}
}
if (j < low) // adjust so low <= j <= i <= high
j = low;
if (i > high)
i = high;
if(j - low <= high - i){
Quick_Sort(ptr, low, j, size, cmp);
low = j + 1;
} else {
if (i < high)
Quick_Sort(ptr, i, high, size, cmp);
high = i - 1;
}
}
}
Эта альтернативная версия немного проще.
void Quick_Sort(const void* ptr, int low, int high, size_t size, int (*cmp)(const void*, const void*))
{
int i;
int j;
char *pivot;
while(low < high){
i = low-1;
j = high+1;
pivot = (char*)ptr + ((low+high)/2) * size;
while (1)
{
while (cmp((char*)ptr + ++i * size, pivot) == -1);
while (cmp((char*)ptr + --j * size, pivot) == 1);
if (i >= j)
break;
Swapper((char*)ptr + i * size, (char*)ptr + j * size, size);
}
if(j - low <= high - j){
Quick_Sort(ptr, low, j, size, cmp);
low = j+1;
} else {
Quick_Sort(ptr, j+1, high, size, cmp);
high = j;
}
}
}
Альтернативная версия без предотвращения переполнения стека:
void Quick_Sort(const void* ptr, int low, int high, size_t size, int (*cmp)(const void*, const void*))
{
int i;
int j;
char *pivot;
if(low >= high)
return;
i = low-1;
j = high+1;
pivot = (char*)ptr + ((low+high)/2) * size;
while (1)
{
while (cmp((char*)ptr + ++i * size, pivot) == -1);
while (cmp((char*)ptr + --j * size, pivot) == 1);
if (i >= j)
break;
Swapper((char*)ptr + i * size, (char*)ptr + j * size, size);
}
Quick_Sort(ptr, low, j, size, cmp);
Quick_Sort(ptr, j+1, high, size, cmp);
}