Участник:Nechaev/Черновик — различия между версиями
Nechaev (обсуждение | вклад) (→Основная идея) |
Nechaev (обсуждение | вклад) м (→Анализ) |
||
| Строка 42: | Строка 42: | ||
В первом алгоритме первые два цикла работают за <tex>\Theta(k)</tex> и <tex>\Theta(n)</tex>, соответственно; двойной цикл за <tex>\Theta(n + k)</tex>. Во втором алгоритме циклы занимают <tex>\Theta(k)</tex>, <tex>\Theta(n)</tex>, <tex>\Theta(k)</tex> и <tex>\Theta(n)</tex>, соответственно. Итого оба алгоритма имеют линейную временную трудоёмкость <tex>\Theta(n + k)</tex>. Используемая память в первом алгоритме равна <tex>\Theta(k)</tex>, а во втором <tex>\Theta(n + k)</tex>. | В первом алгоритме первые два цикла работают за <tex>\Theta(k)</tex> и <tex>\Theta(n)</tex>, соответственно; двойной цикл за <tex>\Theta(n + k)</tex>. Во втором алгоритме циклы занимают <tex>\Theta(k)</tex>, <tex>\Theta(n)</tex>, <tex>\Theta(k)</tex> и <tex>\Theta(n)</tex>, соответственно. Итого оба алгоритма имеют линейную временную трудоёмкость <tex>\Theta(n + k)</tex>. Используемая память в первом алгоритме равна <tex>\Theta(k)</tex>, а во втором <tex>\Theta(n + k)</tex>. | ||
| − | На практике сортировка подсчетом применяется, когда <tex>k = O(n)</tex>, а в этом случае время работы алгоритма равно <tex>\Theta(n)</tex> | + | //--переписать--// На практике сортировка подсчетом применяется, когда <tex>k = O(n)</tex>, а в этом случае время работы алгоритма равно <tex>\Theta(n)</tex> // |
== Источники == | == Источники == | ||
Версия 22:08, 17 мая 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;
Устойчивый алгоритм
В этом варианте помимо входного массива потребуется два вспомогательных массива — для счётчика и для отсортированного массива. Сначала следует заполнить массив нулями, и для каждого увеличить на 1. Далее подсчитывается число элементов меньше или равных текущему. Для этого каждый , начиная с , увеличивают на . На последнем шаге алгоритма читается входной массив с конца и в каждый записывается , а значение уменьшается на 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;
Обобщение на произвольный целочисленный диапазон
Если диапазон значений (min и max) заранее не известен, можно воспользоваться линейным поиском min и max, что не повлияет на асимптотику алгоритма. При работе с массивом из необходимо вычитать min, а при обратной записи прибавлять.
Анализ
В первом алгоритме первые два цикла работают за и , соответственно; двойной цикл за . Во втором алгоритме циклы занимают , , и , соответственно. Итого оба алгоритма имеют линейную временную трудоёмкость . Используемая память в первом алгоритме равна , а во втором .
//--переписать--// На практике сортировка подсчетом применяется, когда , а в этом случае время работы алгоритма равно //
Источники
- Томас Кормен, Чарльз Лейзерсон, Рональд Ривест, Клиффорд Штайн. «Алгоритмы. Построение и анализ» — «Вильямс», 2011 г. — 1296 стр. — ISBN 978-5-8459-0857-5, 5-8459-0857-4, 0-07-013151-1
- Сортировка подсчетом — Википедия