quickSortHaore<E> function
- List<
E> list, { - int? begin,
- int? end,
- Comparator<
E> ? compare, - int threshold = 32,
Sorts the list
of numbers using the
quicksort algorithm following
Hoare partition scheme
with several optimizations.
Parameters
list
is any list of items to be sorted.- To perform partial sorting, you can specify the
begin
orend
. begin
is the start index of the range to be sorted.- If
begin
is negative, range starts at the 0 - If
begin
is not below the length of thelist
, range will be empty. end
is the final index if the range to be sorted. It is exclusive.- If
end
is above the length of thelist
, it will be ignored. - If
end
is negative, the absolute value of it will be subtracted from the length of thelist
to determine where the range ends. - If
end
is not greater than thebegin
, the range will be empty. compare
is a custom compare to order the list elements. If it is null andlist
items are not Comparable, TypeError is thrown.threshold
is the maximum limit for which a range can be sorted using insertion sort.
Optimizations
- Using iterative approach to avoid recursion. (function calls are slow)
- Keeping stack smaller by tail-call optimization. (reduces memory usage)
- Use insertion sort on smaller ranges. (configurable by
threshold
parameter) - Exclude items equal to the pivot to avoid worst-case performance on list with repeatitive items.
- Keeping separate logic for when compare function is provided or not.
Details
Quicksort is a type of divide and conquer algorithm for sorting an array, based on a partitioning routine; the details of this partitioning can vary somewhat, so that quicksort is really a family of closely related algorithms.
Haore partition scheme was proposed by the original developer of quicksort
Tony Haore. This scheme selects the item at the middle of the range as pivot,
then partitions the list
into two parts using two pointers so that all items
on the left part is less or equal to the pivot, and all items on the other part
is greater or equal to the pivot.
Compared to Lomuto's scheme, this scheme uses less swap operations, which actually helps to speed things up by a lot in dart. You can check the benchmarks for a comparison between these two implementations.
Complexity: Time O(n log n)
| Space O(log n)
Worst-case: Time O(n^2)
| Space O(log n)
Implementation
void quickSortHaore<E>(
List<E> list, {
int? begin,
int? end,
Comparator<E>? compare,
int threshold = 32,
}) {
int b, e;
int n = list.length;
// Find the range given the parameters.
b = 0;
e = n;
if (begin != null && b < begin) {
b = begin;
}
if (end != null && end < e) {
e = end;
if (e < 0) e += n;
}
// If the range has less than two items, returns immediately.
if (b + 1 >= e) return;
// add the range to a stack.
if (compare == null) {
quickSortDefault(list, b, e, threshold);
} else {
quickSortCustom(list, b, e, threshold, compare);
}
}