Просмотр отдельных изменений

Фильтры правок (обсуждение) — это автоматизированный механизм проверок правок участников.
(Список | Последние изменения фильтров | Изучение правок | Журнал срабатываний)
Перейти к навигации Перейти к поиску

Эта страница позволяет вам проверить переменные, сгенерированные фильтром злоупотреблений, на предмет отдельного изменения.

Переменные, созданные для этого изменения

ПеременнаяЗначение
Имя учётной записи ($1) (user_name)
'80.255.21.66'
ID страницы ($1) (page_id)
190157
Пространство имён страницы ($1) (page_namespace)
0
Название страницы (без пространства имён) ($1) (page_title)
'Сортировка подсчётом'
Полное название страницы ($1) (page_prefixedtitle)
'Сортировка подсчётом'
Действие ($1) (action)
'edit'
Описание правки/причина ($1) (summary)
''
Была ли правка отмечена как «малое изменение» (больше не используется) (minor_edit)
false
Вики-текст старой страницы до правки ($1) (old_wikitext)
''''Сортировка подсчётом''' — [[алгоритм сортировки]], в котором используется диапазон чисел сортируемого [[массив]]а ([[Список (информатика)|списка]]) для подсчёта совпадающих элементов. Применение сортировки подсчётом целесообразно лишь тогда, когда сортируемые числа имеют (или их можно отобразить в) диапазон возможных значений, который достаточно мал по сравнению с сортируемым множеством, например, миллион натуральных чисел меньших 1000. Эффективность алгоритма падает, если при попадании нескольких различных элементов в одну ячейку, их надо дополнительно сортировать. Необходимость сортировки внутри ячеек лишает алгоритм смысла, так как каждый элемент придётся просматривать более одного раза. Предположим, что входной массив состоит из <math>n</math> целых чисел в диапазоне от 0 до <math>k - 1</math>, где <math>k \in \mathbb N</math>. Далее алгоритм будет обобщён для произвольного целочисленного диапазона. Существует несколько модификаций сортировки подсчётом, ниже рассмотрены три линейных и одна квадратичная, которая использует другой подход, но имеет то же название. == Простой алгоритм == Это простейший вариант алгоритма. Создать вспомогательный массив <code>C[0..k - 1]</code>, состоящий из нулей, затем последовательно прочитать элементы входного массива <code>A</code>, для каждого <code>A[i]</code> увеличить <code>C[A[i]]</code> на единицу. Теперь достаточно пройти по массиву <code>C</code>, для каждого <math>j \in \{0, ..., k - 1\}</math> в массив <code>A</code> последовательно записать число <code>j C[j]</code> раз. <code> SimpleCountingSort for i = 0 to k - 1 C[i] = 0; for i = 0 to n - 1 C[A[i]] = C[A[i]] + 1; b = 0; for j = 0 to k - 1 for i = 0 to C[j] - 1 A[b] = j; b = b + 1;</code> == Алгоритм со списком == Этот вариант ({{lang-en|pigeonhole sorting, count sort}}) используется, когда на вход подается массив структур данных, который следует отсортировать по ключам (<code>key</code>). Нужно создать вспомогательный массив <code>C[0..k - 1]</code>, каждый <code>C[i]</code> в дальнейшем будет содержать список элементов из входного массива. Затем последовательно прочитать элементы входного массива <code>A</code>, каждый <code>A[i]</code> добавить в список <code>C[A[i].key]</code>. В заключении пройти по массиву <code>C</code>, для каждого <math>j \in \{0, ..., k - 1\}</math> в массив <code>A</code> последовательно записывать элементы списка <code>C[j]</code>. [[устойчивая сортировка|Алгоритм устойчив]]. <code> ListCountingSort for i = 0 to k - 1 C[i] = NULL; for i = 0 to n - 1 C[A[i].key].add(A[i]); b = 0; for j = 0 to k - 1 p = C[j]; while p != NULL A[b] = p.data; p = p.next(); b = b + 1;</code> == Устойчивый алгоритм == В этом варианте помимо входного массива <code>A</code> потребуется два вспомогательных массива — <code>C[0..k - 1]</code> для счётчика и <code>B[0..n - 1]</code> для отсортированного массива. Сначала следует заполнить массив <code>C</code> нулями, и для каждого <code>A[i]</code> увеличить <code>C[A[i]]</code> на 1. Далее подсчитывается число элементов меньше или равных текущему. Для этого каждый <code>C[j]</code>, начиная с <code>C[1]</code>, увеличивают на <code>C[j - 1]</code>. На последнем шаге алгоритма читается входной массив с конца, значение <code>C[A[i]]</code> уменьшается на 1 и в каждый <code>B[C[A[i]]]</code> записывается <code>A[i]</code>. Алгоритм устойчив. <code> StableCountingSort for i = 0 to k - 1 C[i] = 0; for i = 0 to n - 1 C[A[i]] = C[A[i]] + 1; for j = 1 to k - 1 C[j] = C[j] + C[j - 1]; for i = n - 1 to 0 C[A[i]] = C[A[i]] - 1; B[C[A[i]]] = A[i];</code> == Обобщение на произвольный целочисленный диапазон == Возникает несколько вопросов. Что делать, если диапазон значений (min и max) заранее не известен? Что делать, если минимальное значение больше нуля или в сортируемых данных присутствуют отрицательные числа? Первый вопрос можно решить линейным поиском min и max, что не повлияет на асимптотику алгоритма. Второй вопрос несколько сложнее. Если min больше нуля, то следует при работе с массивом <code>C</code> из <code>A[i]</code> вычитать min, а при обратной записи прибавлять. При наличии отрицательных чисел нужно при работе с массивом <code>C</code> к <code>A[i]</code> прибавлять |min|, а при обратной записи вычитать. == Анализ == В первых двух алгоритмах первые два цикла работают за [[Теория сложности вычислений|<math>\Theta(k)</math>]] и <math>\Theta(n)</math>, соответственно; двойной цикл за <math>\Theta(n + k)</math>. В третьем алгоритме циклы занимают <math>\Theta(k)</math>, <math>\Theta(n)</math>, <math>\Theta(k)</math> и <math>\Theta(n)</math>, соответственно. Итого все три алгоритма имеют линейную временную трудоёмкость <math>\Theta(n + k)</math>. Используемая память в первых двух алгоритмах равна <math>\Theta(k)</math>, а в третьем <math>\Theta(n + k)</math>. == Квадратичный алгоритм сортировки подсчётом == Также сортировкой подсчётом называют немного другой алгоритм. В нём используются входной массив <code>A</code> и вспомогательный массив <code>B</code> для отсортированного множества. В алгоритме следует для каждого элемента входного массива <code>A[i]</code> подсчитать количество элементов меньших него <math>c_1</math> и количество элементов, равных ему, но стоящих ранее <math>c_2</math> (<math>c = c_1 + c_2</math>). <code>B[c]</code> присвоить <code>A[i]</code>. Алгоритм устойчив. <code> SquareCountingSort for i = 0 to n - 1 c = 0; for j = 0 to n - 1 if A[j] < A[i] c = c + 1; for j = 0 to i - 1 if A[i] == A[j] c = c + 1; B[c] = A[i];</code> === Анализ === Очевидно, временная оценка алгоритма равна <math>\Theta(n^2)</math>, память <math>\Theta(n)</math>. == Примеры реализации == === C === Простой алгоритм. <source lang="c"> void CountingSort (int *a, int n, int min, int max) { int i, j, c; int *b; assert(n > 0); assert(min <= max); b = (int *)calloc(max - min + 1, sizeof(int)); assert(b != NULL); for (i = 0; i <= n - 1; ++i) ++b[a[i] - min]; for (j = min; j <= max; ++j) { c = b[j - min]; while (c > 0) { *a = j; ++a; --c; } } free(b); } </source> === [[Компонентный Паскаль]] === Простой алгоритм. <source lang="pascal"> PROCEDURE CountingSort (VAR a: ARRAY OF INTEGER; min, max: INTEGER); VAR i, j, c: INTEGER; b: POINTER TO ARRAY OF INTEGER; BEGIN ASSERT(min <= max); NEW(b, max - min + 1); FOR i := 0 TO LEN(a) - 1 DO INC(b[a[i] - min]) END; i := 0; FOR j := min TO max DO c := b[j - min]; WHILE c > 0 DO a[i] := j; INC(i); DEC(c) END END END CountingSort; </source> === C# === Квадратичный алгоритм сортировки подсчётом <source lang="csharp"> using System; class Program { static void Main(string[] args) { //генерация массива для примера Random rnd=new Random(); int[] arr=(new int[100]).Select(x => rnd.Next(10)).ToArray(); int[] b = new int[100]; //сам алгоритм for (int i = 0; i < arr.Length ; i++) { int c = 0; for (int j = 0; j < arr.Length ; j++) { if (arr[j] < arr[i]) { c++; } } for (int j = 0; j < i ; j++) { if (arr[i] == arr[j]) { c++; } } b[c] = arr[i]; } } } </source> == См. также == * [[Алгоритм сортировки]] * [[O-большое]] * [[Временная сложность алгоритма]] * [[Ёмкостная сложность алгоритма]] == Литература == * {{книга |часть = '''Глава 7. Пространственно-временной компромисс: Сортировка подсчетом''' |заглавие = Алгоритмы: введение в разработку и анализ |оригинал = Introduction to The Design and Analysis of Aigorithms |автор = Ананий В. Левитин |ссылка = |isbn = 5-8459-0987-2 |страницы = 307 - 310 |год = 2006 |место = М. |издательство = [[Вильямс (издательство)|«Вильямс»]] }} * {{книга |часть = '''Глава 8. Сортировка за линейное время''' |заглавие = Алгоритмы: построение и анализ |оригинал = Introduction to Algorithms |автор = Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн, Клифорд |ссылка = |издание = 2-e издание |isbn = 5-8459-0857-4 |страницы = 224 - 226 |год = 2005 |место = М. |издательство = [[Вильямс (издательство)|«Вильямс»]] }} == Ссылки == * [http://rain.ifmo.ru/cat/view.php/vis/sorts/linear-2005 Визуализатор1] — Java-аплет. * [http://rain.ifmo.ru/cat/view.php/vis/sorts/linear-2001 Визуализатор2] — Java-аплет. {{Алгоритмы сортировки}} [[Категория:Алгоритмы сортировки]] [[cs:Counting sort]] [[de:Countingsort]] [[en:Counting sort]] [[es:Ordenamiento por cuentas]] [[fa:مرتب‌سازی شمارشی]] [[fi:Laskentalajittelu]] [[fr:Tri comptage]] [[he:מיון מנייה]] [[it:Counting sort]] [[ml:കൗണ്ടിങ്ങ് സോർട്ട്]] [[nl:Counting sort]] [[pl:Sortowanie przez zliczanie]] [[pt:Counting sort]] [[tr:Sayarak sıralama]] [[uk:Сортування підрахунком]] [[zh:计数排序]]'
Вики-текст новой страницы после правки ($1) (new_wikitext)
'xzzxczxczxczczzxczxczxczxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxczzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzdfsdfsdfsdfsdfsdfxc vxcbdfbgsdfzscvxcbsfvgxcvxcbvfbgasdfxcvzsdnnnjxnjxcvnxcvxcvxcxcvnjxjkcvjkxcvjkvnkjxcnvjkxcnvjknxckvjxcjkvnjkxcvnkxcvnjkxnvjkxcvkxcnvjkxnvjkxcnvkjnxvkxnkvnxvknxkvnxcjkvnkxcvnjkxvnkjxcvnjkxcvnjkxcvnkxcnkxcvnkxcjvnjkxcvnjkxcvnjkxcvnjkxcvnjkxcvnjkxnvjkvnjkxcnvjkxcnvkjx'
Была ли правка сделана через выходной узел сети Tor (tor_exit_node)
0
Unix-время изменения ($1) (timestamp)
1270877555