mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 11:57:35 +00:00
AK: Guarantee a maximum stack depth for dual_pivot_quick_sort
When the two chosen pivots happen to be the smallest and largest elements of the array, three partitions will be created, two of size 0 and one of size n-2. If this happens on each recursive call to dual_pivot_quick_sort, the stack depth will reach approximately n/2. To avoid the stack from deepening, iteration can be used for the largest of the three partitions. This ensures the stack depth will only increase for partitions of size n/2 or smaller, which results in a maximum stack depth of log(n).
This commit is contained in:
parent
67b0d04315
commit
c9f3cc6dcc
1 changed files with 62 additions and 49 deletions
|
@ -18,11 +18,8 @@ namespace AK {
|
||||||
template<typename Collection, typename LessThan>
|
template<typename Collection, typename LessThan>
|
||||||
void dual_pivot_quick_sort(Collection& col, int start, int end, LessThan less_than)
|
void dual_pivot_quick_sort(Collection& col, int start, int end, LessThan less_than)
|
||||||
{
|
{
|
||||||
|
while (start < end) {
|
||||||
int size = end - start + 1;
|
int size = end - start + 1;
|
||||||
if (size <= 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size > 3) {
|
if (size > 3) {
|
||||||
int third = size / 3;
|
int third = size / 3;
|
||||||
if (less_than(col[start + third], col[end - third])) {
|
if (less_than(col[start + third], col[end - third])) {
|
||||||
|
@ -71,9 +68,25 @@ void dual_pivot_quick_sort(Collection& col, int start, int end, LessThan less_th
|
||||||
int left_pointer = j;
|
int left_pointer = j;
|
||||||
int right_pointer = g;
|
int right_pointer = g;
|
||||||
|
|
||||||
dual_pivot_quick_sort(col, start, left_pointer - 1, less_than);
|
int left_size = left_pointer - start;
|
||||||
|
int middle_size = right_pointer - (left_pointer + 1);
|
||||||
|
int right_size = (end + 1) - (right_pointer + 1);
|
||||||
|
|
||||||
|
if (left_size >= middle_size && left_size >= right_size) {
|
||||||
dual_pivot_quick_sort(col, left_pointer + 1, right_pointer - 1, less_than);
|
dual_pivot_quick_sort(col, left_pointer + 1, right_pointer - 1, less_than);
|
||||||
dual_pivot_quick_sort(col, right_pointer + 1, end, less_than);
|
dual_pivot_quick_sort(col, right_pointer + 1, end, less_than);
|
||||||
|
end = left_pointer - 1;
|
||||||
|
} else if (middle_size >= right_size) {
|
||||||
|
dual_pivot_quick_sort(col, start, left_pointer - 1, less_than);
|
||||||
|
dual_pivot_quick_sort(col, right_pointer + 1, end, less_than);
|
||||||
|
start = left_pointer + 1;
|
||||||
|
end = right_pointer - 1;
|
||||||
|
} else {
|
||||||
|
dual_pivot_quick_sort(col, start, left_pointer - 1, less_than);
|
||||||
|
dual_pivot_quick_sort(col, left_pointer + 1, right_pointer - 1, less_than);
|
||||||
|
start = right_pointer + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Iterator, typename LessThan>
|
template<typename Iterator, typename LessThan>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue