radixSortOf<E> function
void
radixSortOf<E>(})
Sorts any list
of items using
radix sort algorithm
with a radix value of 2^p
.
Parameters
list
is any list of integers to be sorted.radixPower
is the value ofp
in2^p
that is used as the radix.- 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. - Set
reversed
totrue
if you want to sort in descending order.
Details
This function maps the list
of items with the keyOf
to generate a list
of numbers. radixSort is applied to this list of numbers, and a sorted
list is reconstructed with the mapped values from these numbers.
Complexity: Time O(n * log_b n)
| Space O(n)
(where, b
is the radix)
Implementation
void radixSortOf<E>(
List<E> list,
KeyOf<E, int> keyOf, {
int? begin,
int? end,
bool reversed = false,
int? radixPower,
}) {
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 (b + 1 >= e) return;
int p = radixPower ?? (0.5 * log(n) / log(2)).ceil();
if (p < 1) {
throw RangeError("Radix power should be at least 2 or above");
}
// sorts range `[b, e)` with radix 2^p
int l, h, i, j, k, m;
List<int> keys =
List<int>.generate(e, (i) => keyOf(list[i]), growable: false);
// Find the minimum and maximum numbers in range [b, e)
l = keys[b];
h = keys[b];
for (i = b + 1; i < e; ++i) {
if (keys[i] < l) {
l = keys[i];
}
if (keys[i] > h) {
h = keys[i];
}
}
int mask = (1 << p) - 1;
List<List<E>> valueBins =
List<List<E>>.generate(mask + 1, (i) => <E>[], growable: false);
List<List<int>> keyBins =
List<List<int>>.generate(mask + 1, (i) => <int>[], growable: false);
// Put items inside the bin
for (k = 0; ((h - l) >> k) != 0; k += p) {
// Put items to bin using the mask
for (i = b; i < e; i++) {
m = ((keys[i] - l) >> k) & mask;
keyBins[m].add(keys[i]);
valueBins[m].add(list[i]);
}
// Reconstruct the list from bin
i = b;
for (m = 0; m <= mask; m++) {
for (j = 0; j < keyBins[m].length; ++j) {
keys[i] = keyBins[m][j];
list[i] = valueBins[m][j];
i++;
}
keyBins[m].clear();
valueBins[m].clear();
}
}
if (reversed) {
// reverse the order of the list
reverseList(list, b, e);
}
}