Сортировка подсчётом — различия между версиями
Nechaev (обсуждение | вклад) м (→Источники) |
Nechaev (обсуждение | вклад) |
||
Строка 2: | Строка 2: | ||
== Основная идея == | == Основная идея == | ||
− | + | ||
== Простой алгоритм == | == Простой алгоритм == | ||
Строка 20: | Строка 20: | ||
== Устойчивый алгоритм == | == Устойчивый алгоритм == | ||
+ | |||
+ | ==== Идея ==== | ||
+ | |||
+ | Основная идея состоит в том, чтобы для каждого элемента входного массива подсчитать количество элементов, меньших данного. Эта информация будет указывать на позиции элементов в отсортированном массиве. Например, если для элемента <tex>x</tex> количество таких элементов будет <tex>42</tex>, то <tex>x</tex> будет занимать <tex>43</tex>-ю позицию в отсортированном массиве. Если элементы могут иметь одинаковые значения, то необходимо модифицировать алгоритм, так как нельзя разместить все такие элементы в одну позицию. | ||
+ | |||
+ | ==== Реализация ==== | ||
+ | |||
В этом варианте помимо входного массива <tex>A</tex> потребуется два вспомогательных массива — <tex>C[0..k - 1]</tex> для счётчика и <tex>B[0..n - 1]</tex> для отсортированного массива. Сначала следует заполнить массив <tex>C</tex> нулями, и для каждого <tex>A[i]</tex> увеличить <tex>C[A[i]]</tex> на 1. Далее подсчитывается число элементов меньше или равных текущему. Для этого каждый <tex>C[number]</tex>, начиная с <tex>C[1]</tex>, увеличивают на <tex>C[number - 1]</tex>. На последнем шаге алгоритма читается входной массив с конца и в каждый <tex>B[C[A[i]]]</tex> записывается <tex>A[i]</tex>, а значение <tex>C[A[i]]</tex> уменьшается на 1. Алгоритм устойчив. Устойчивость может потребоваться при [[Сортировка_подсчетом_сложных_объектов|сортировке сложных структур данных]]. | В этом варианте помимо входного массива <tex>A</tex> потребуется два вспомогательных массива — <tex>C[0..k - 1]</tex> для счётчика и <tex>B[0..n - 1]</tex> для отсортированного массива. Сначала следует заполнить массив <tex>C</tex> нулями, и для каждого <tex>A[i]</tex> увеличить <tex>C[A[i]]</tex> на 1. Далее подсчитывается число элементов меньше или равных текущему. Для этого каждый <tex>C[number]</tex>, начиная с <tex>C[1]</tex>, увеличивают на <tex>C[number - 1]</tex>. На последнем шаге алгоритма читается входной массив с конца и в каждый <tex>B[C[A[i]]]</tex> записывается <tex>A[i]</tex>, а значение <tex>C[A[i]]</tex> уменьшается на 1. Алгоритм устойчив. Устойчивость может потребоваться при [[Сортировка_подсчетом_сложных_объектов|сортировке сложных структур данных]]. | ||
<code> | <code> |
Версия 15:04, 23 мая 2012
Сортировка подсчётом — алгоритм сортировки целых чисел в диапазоне от
до некоторой константы , работающий за линейное время.Содержание
Основная идея
Простой алгоритм
Это простейший вариант алгоритма. Создать вспомогательный массив
SimpleCountingSort for number = 0 to k - 1 C[number] = 0; for i = 0 to length[A] - 1 C[A[i]] = C[A[i]] + 1; pos = 0; for number = 0 to k - 1 for i = 0 to C[j] - 1 A[pos] = number; pos = pos + 1;
Устойчивый алгоритм
Идея
Основная идея состоит в том, чтобы для каждого элемента входного массива подсчитать количество элементов, меньших данного. Эта информация будет указывать на позиции элементов в отсортированном массиве. Например, если для элемента
количество таких элементов будет , то будет занимать -ю позицию в отсортированном массиве. Если элементы могут иметь одинаковые значения, то необходимо модифицировать алгоритм, так как нельзя разместить все такие элементы в одну позицию.Реализация
В этом варианте помимо входного массива сортировке сложных структур данных.
StableCountingSort for number = 0 to k - 1 C[number] = 0; for i = 0 to length[A] - 1 C[A[i]] = C[A[i]] + 1; for number = 1 to k - 1 C[j] = C[j] + C[j - 1]; for i = length[A] - 1 to 0 B[C[A[i]]] = A[i]; C[A[i]] = C[A[i]] - 1;
Обобщение на произвольный целочисленный диапазон
Если диапазон значений (минимимум и максимум) заранее не известен, можно воспользоваться их линейным поиском, что не повлияет на асимптотику алгоритма. При работе с массивом
из необходимо вычитать минимум, а при обратной записи прибавлять.Анализ
В первом алгоритме первые два цикла работают за
и , соответственно; двойной цикл за . Во втором алгоритме циклы занимают , , и , соответственно. Итого оба алгоритма имеют линейную временную трудоёмкость . Используемая память в первом алгоритме равна , а во втором .Использование сортировки подсчётом целесообразно, когда диапазон возможных значений входных данных достаточно мал по сравнению с количеством элементов в сортируемом множестве, например, если
и все элементы натуральные числа меньшие , то время работы алгоритма равно . Эффективность алгоритма падает, когда необходимо сортировать различные элементы, попавшие в одну ячейку.Источники
- Томас Кормен, Чарльз Лейзерсон, Рональд Ривест, Клиффорд Штайн. «Алгоритмы. Построение и анализ» — «Вильямс», 2011 г. — 1296 стр. — ISBN 978-5-8459-0857-5, 5-8459-0857-4, 0-07-013151-1
- Сортировка подсчетом — Википедия