countingSortOf<E> function
void
countingSortOf<E>(})
Sorts any list
of items using
counting sort algorithm.
Parameters
list
is any list of integers to be sorted.keyOf
is an mapping function to get the integer value of the item.- 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. countingSort is applied to this list of numbers, and a sorted
list is reconstructed with the mapped values from these numbers.
Complexity: Time O(n + k)
| Space O(n + k)
(k
is the range of the keys)
Implementation
void countingSortOf<E>(
List<E> list,
KeyOf<E, int> keyOf, {
int? begin,
int? end,
bool reversed = false,
}) {
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;
/// sorts range `[b, e)`
int l, h, m, i, j, k;
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];
}
}
m = h - l + 1;
List<int> count = List<int>.filled(m, 0, growable: false);
List<E> values = List<E>.filled(m, list[b], growable: false);
// Count frequencies of the numbers
for (i = b; i < e; ++i) {
count[keys[i] - l]++;
values[keys[i] - l] = list[i];
}
// Reconstruct a sorted list
k = b;
for (i = 0; i < m; ++i) {
for (j = count[i]; j > 0; --j) {
list[k++] = values[i];
}
}
if (reversed) {
// reverse the order of the list
reverseList(list, b, e);
}
}