From 67b0d04315449dd4f780b21c4f156f89e7b635ef Mon Sep 17 00:00:00 2001 From: Mart G Date: Wed, 28 Apr 2021 16:53:10 +0200 Subject: [PATCH] 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. --- AK/QuickSort.h | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/AK/QuickSort.h b/AK/QuickSort.h index 2112be95bf..cef2a001fe 100644 --- a/AK/QuickSort.h +++ b/AK/QuickSort.h @@ -18,13 +18,24 @@ namespace AK { template 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);