mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-12 02:30:30 +09:00
AK: Dual pivot quicksort implementation (#1838)
This commit is contained in:
parent
54550365eb
commit
75f6454de7
Notes:
sideshowbarker
2024-07-19 07:30:42 +09:00
Author: https://github.com/wilsonk 🔰
Commit: 75f6454de7
Pull-request: https://github.com/SerenityOS/serenity/pull/1838
1 changed files with 58 additions and 2 deletions
|
@ -30,6 +30,61 @@
|
||||||
|
|
||||||
namespace AK {
|
namespace AK {
|
||||||
|
|
||||||
|
/* This is a dual pivot quick sort. It is quite a bit faster than the single
|
||||||
|
* pivot quick_sort below. The other quick_sort below should only be used when
|
||||||
|
* you are stuck with simple iterators to a container and you don't have access
|
||||||
|
* to the container itself.
|
||||||
|
*/
|
||||||
|
template<typename Collection, typename LessThan>
|
||||||
|
void dual_pivot_quick_sort(Collection& col, int start, int end, LessThan less_than)
|
||||||
|
{
|
||||||
|
if (start >= end) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int left_pointer, right_pointer;
|
||||||
|
if (!less_than(col[start], col[end])) {
|
||||||
|
swap(col[start], col[end]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int j = start + 1;
|
||||||
|
int k = start + 1;
|
||||||
|
int g = end - 1;
|
||||||
|
|
||||||
|
auto left_pivot = col[start];
|
||||||
|
auto right_pivot = col[end];
|
||||||
|
|
||||||
|
while (k <= g) {
|
||||||
|
if (less_than(col[k], left_pivot)) {
|
||||||
|
swap(col[k], col[j]);
|
||||||
|
j++;
|
||||||
|
} else if (!less_than(col[k], right_pivot)) {
|
||||||
|
while (!less_than(col[g], right_pivot) && k < g) {
|
||||||
|
g--;
|
||||||
|
}
|
||||||
|
swap(col[k], col[g]);
|
||||||
|
g--;
|
||||||
|
if (less_than(col[k], left_pivot)) {
|
||||||
|
swap(col[k], col[j]);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
j--;
|
||||||
|
g++;
|
||||||
|
|
||||||
|
swap(col[start], col[j]);
|
||||||
|
swap(col[end], col[g]);
|
||||||
|
|
||||||
|
left_pointer = j;
|
||||||
|
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);
|
||||||
|
dual_pivot_quick_sort(col, right_pointer + 1, end, less_than);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Iterator, typename LessThan>
|
template<typename Iterator, typename LessThan>
|
||||||
void quick_sort(Iterator start, Iterator end, LessThan less_than)
|
void quick_sort(Iterator start, Iterator end, LessThan less_than)
|
||||||
{
|
{
|
||||||
|
@ -65,13 +120,14 @@ void quick_sort(Iterator start, Iterator end)
|
||||||
template<typename Collection, typename LessThan>
|
template<typename Collection, typename LessThan>
|
||||||
void quick_sort(Collection& collection, LessThan less_than)
|
void quick_sort(Collection& collection, LessThan less_than)
|
||||||
{
|
{
|
||||||
quick_sort(collection.begin(), collection.end(), move(less_than));
|
dual_pivot_quick_sort(collection, 0, collection.size() - 1, move(less_than));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Collection>
|
template<typename Collection>
|
||||||
void quick_sort(Collection& collection)
|
void quick_sort(Collection& collection)
|
||||||
{
|
{
|
||||||
quick_sort(collection.begin(), collection.end());
|
dual_pivot_quick_sort(collection, 0, collection.size() - 1,
|
||||||
|
[](auto& a, auto& b) { return a < b; });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue