AK: Change pivot selection of dual_pivot_quick_sort

Picking the first and last elements as pivots makes it so that
a sorted array is the worst-case input for the algorithm.

This change instead picks pivots at approximately 1/3 and 2/3 in
the array. This results in desired performance for sorted arrays.

Of course this only changes which inputs result in worst-case
performance, but hopefully those inputs occur less frequently than
already sorted arrays.
This commit is contained in:
Mart G 2021-04-28 16:53:10 +02:00 committed by Andreas Kling
parent edfe81b1ee
commit 67b0d04315
Notes: sideshowbarker 2024-07-18 19:00:11 +09:00

View File

@ -18,13 +18,24 @@ namespace AK {
template<typename Collection, typename LessThan>
void dual_pivot_quick_sort(Collection& col, int start, int end, LessThan less_than)
{
if (start >= end) {
int size = end - start + 1;
if (size <= 1) {
return;
}
int left_pointer, right_pointer;
if (!less_than(col[start], col[end])) {
swap(col[start], col[end]);
if (size > 3) {
int third = size / 3;
if (less_than(col[start + third], col[end - third])) {
swap(col[start + third], col[start]);
swap(col[end - third], col[end]);
} else {
swap(col[start + third], col[end]);
swap(col[end - third], col[start]);
}
} else {
if (!less_than(col[start], col[end])) {
swap(col[start], col[end]);
}
}
int j = start + 1;
@ -57,8 +68,8 @@ void dual_pivot_quick_sort(Collection& col, int start, int end, LessThan less_th
swap(col[start], col[j]);
swap(col[end], col[g]);
left_pointer = j;
right_pointer = g;
int left_pointer = j;
int right_pointer = g;
dual_pivot_quick_sort(col, start, left_pointer - 1, less_than);
dual_pivot_quick_sort(col, left_pointer + 1, right_pointer - 1, less_than);