<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=188.130.155.152&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=188.130.155.152&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/188.130.155.152"/>
		<updated>2026-05-19T17:59:55Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A6%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D1%8F_%D1%81%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0&amp;diff=64844</id>
		<title>Цифровая сортировка</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A6%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D1%8F_%D1%81%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0&amp;diff=64844"/>
				<updated>2018-04-07T00:05:30Z</updated>
		
		<summary type="html">&lt;p&gt;188.130.155.152: cnt[j] должен уменьшаться при формировании вспомогательного массива&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
'''Цифровая сортировка''' (англ. ''radix sort'') {{---}} один из алгоритмов сортировки, использующих внутреннюю структуру сортируемых объектов.&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
[[Файл:Цифровая_сортировка.png|thumb|right|450px|Пример цифровой сортировки трехзначных чисел, начиная с младших разрядов]]&lt;br /&gt;
[[Файл:Msd-sort.png|thumb|right|450px|Пример цифровой сортировки трехзначных чисел, начиная со старших разрядов]]&lt;br /&gt;
Имеем множество последовательностей одинаковой длины, состоящих из элементов, на которых задано [[Отношение порядка|отношение линейного порядка]]. Требуется отсортировать эти последовательности в лексикографическом порядке.&lt;br /&gt;
&lt;br /&gt;
По аналогии с разрядами чисел будем называть элементы, из которых состоят сортируемые объекты, разрядами. Сам алгоритм состоит в последовательной сортировке объектов какой-либо устойчивой сортировкой по каждому разряду, в порядке от младшего разряда к старшему, после чего последовательности будут расположены в требуемом порядке.&lt;br /&gt;
&lt;br /&gt;
Примерами объектов, которые удобно разбивать на разряды и сортировать по ним, являются числа и строки.&lt;br /&gt;
&lt;br /&gt;
*Для чисел уже существует понятие разряда, поэтому будем представлять числа как последовательности разрядов. Конечно, в разных системах счисления разряды одного и того же числа отличаются, поэтому перед сортировкой представим числа в удобной для нас системе счисления.&lt;br /&gt;
&lt;br /&gt;
*Строки представляют из себя последовательности символов, поэтому в качестве разрядов в данном случае выступают отдельные символы, сравнение которых обычно происходит по соответствующим им кодам из [[Представление символов, таблицы кодировок#Таблицы кодировок|таблицы кодировок]]. Для такого разбиения самый младший разряд {{---}} последний символ строки.&lt;br /&gt;
&lt;br /&gt;
Для вышеперечисленных объектов наиболее часто в качестве устойчивой сортировки применяют [[сортировка подсчетом|сортировку подсчетом]].&lt;br /&gt;
&lt;br /&gt;
Такой подход к алгоритму называют '''LSD-сортировкой''' (Least Significant Digit radix sort). Существует модификация алгоритма цифровой сортировки, анализирующая значения разрядов, начиная слева, с наиболее значащих разрядов. Данный алгоритм известен, как '''MSD-сортировка''' (Most Significant Digit radix sort).&lt;br /&gt;
=== Корректность алгоритма LSD-сортировки ===&lt;br /&gt;
Докажем, что данный алгоритм работает верно, используя метод математической индукции по номеру разряда. Пусть &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; {{---}} количество разрядов в сортируемых объектах.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; База&amp;lt;/b&amp;gt;: &amp;lt;tex&amp;gt; n = 1 &amp;lt;/tex&amp;gt;. Очевидно, что алгоритм работает верно, потому что в таком случае мы просто сортируем младшие разряды какой-то заранее выбранной устойчивой сортировкой.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; Переход&amp;lt;/b&amp;gt;: Пусть для &amp;lt;tex&amp;gt; n = k &amp;lt;/tex&amp;gt; алгоритм правильно отсортировал последовательности по &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt; младшим разрядам. Покажем, что в таком случае, при сортировке по &amp;lt;tex&amp;gt; (k + 1) &amp;lt;/tex&amp;gt;-му разряду, последовательности также будут отсортированы в правильном порядке. &lt;br /&gt;
&lt;br /&gt;
Вспомогательная сортировка разобьет все объекты на группы, в которых &amp;lt;tex&amp;gt; (k + 1) &amp;lt;/tex&amp;gt;-й разряд объектов одинаковый. Рассмотрим такие группы. Для сортировки по отдельным разрядам мы используем устойчивую сортировку, следовательно порядок объектов с одинаковым &amp;lt;tex&amp;gt; (k + 1) &amp;lt;/tex&amp;gt;-м разрядом не изменился. Но по предположению индукции по предыдущим &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt; разрядам последовательности были отсортированы правильно, и поэтому в каждой такой группе они будут отсортированы верно. Также верно, что сами группы находятся в правильном относительно друг друга порядке, а, следовательно, и все объекты отсортированы правильно по &amp;lt;tex&amp;gt; (k + 1) &amp;lt;/tex&amp;gt;-м младшим разрядам.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
=== LSD-сортировка ===&lt;br /&gt;
В качестве примера рассмотрим сортировку чисел. Как говорилось выше, в такой ситуации в качестве устойчивой сортировки применяют сортировку подсчетом, так как обычно количество различных значений разрядов не превосходит количества сортируемых элементов. Ниже приведен псевдокод цифровой сортировки, которой подается массив &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; размера &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt;-разрядных чисел . Сам по себе алгоритм представляет собой цикл по номеру разряда, на каждой итерации которого элементы массива &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; размещаются в нужном порядке во вспомогательном массиве &amp;lt;tex&amp;gt; B &amp;lt;/tex&amp;gt;. Для подсчета количества объектов, &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;-й разряд которых одинаковый, а затем и для определения положения объектов в массиве &amp;lt;tex&amp;gt; B &amp;lt;/tex&amp;gt; используется вспомогательный массив &amp;lt;tex&amp;gt; C &amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt; \mathrm{digit(x, i)} &amp;lt;/tex&amp;gt; возвращает &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;-й разряд числа &amp;lt;tex&amp;gt; x &amp;lt;/tex&amp;gt;. Также считаем, что значения разрядов меньше &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;.&lt;br /&gt;
  '''function''' radixSort(int[] A):&lt;br /&gt;
      '''for''' i = 1 '''to''' m               &lt;br /&gt;
          '''for''' j = 0 '''to''' k - 1                              &lt;br /&gt;
              C[j] = 0                                  &lt;br /&gt;
          '''for''' j = 0 '''to''' n - 1&lt;br /&gt;
              d = digit(A[j], i)&lt;br /&gt;
              C[d]++&lt;br /&gt;
          count = 0&lt;br /&gt;
          '''for''' j = 0 '''to''' k - 1&lt;br /&gt;
              tmp = C[j]&lt;br /&gt;
              C[j] = count&lt;br /&gt;
              count += tmp&lt;br /&gt;
          '''for''' j = 0 '''to''' n - 1&lt;br /&gt;
              d = digit(A[j], i)                             &lt;br /&gt;
              B[C[d]] = A[j]            &lt;br /&gt;
              C[d]++&lt;br /&gt;
          A = B&lt;br /&gt;
&lt;br /&gt;
=== MSD-сортировка ===&lt;br /&gt;
Будем считать, что у всех элементов одинаковое число разрядов. Если это не так, то положим на более старших разрядах элементы с самым маленьким значением — для чисел это &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;. Сначала исходный массив делится на &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; частей, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; — основание, выбранное для представления сортируемых объектов. Эти части принято называть &amp;quot;корзинами&amp;quot; или &amp;quot;карманами&amp;quot;. В первую корзину попадают элементы, у которых старший разряд с номером &amp;lt;tex&amp;gt;d = 0&amp;lt;/tex&amp;gt; имеет значение &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;. Во вторую корзину попадают элементы, у которых старший разряд с номером &amp;lt;tex&amp;gt;d = 0&amp;lt;/tex&amp;gt; имеет значение &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и так далее. Затем элементы, попавшие в разные корзины, подвергаются рекурсивному разделению по следующему разряду с номером &amp;lt;tex&amp;gt;d = 1&amp;lt;/tex&amp;gt;. Рекурсивный процесс разделения продолжается, пока не будут перебраны все разряды сортируемых объектов и пока размер корзины больше единицы. То есть останавливаемся когда &amp;lt;tex&amp;gt;d &amp;gt; m&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;l \geqslant r&amp;lt;/tex&amp;gt;, где m — максимальное число разрядов в сортируемых объектах, &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; — левая и правая границы отрезка массива &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В основу распределения элементов по корзинам положен метод распределяющего подсчета элементов с одинаковыми значениями в сортируемом разряде. Для этого выполняется просмотр массива и подсчет количества элементов с различными значениями в сортируемом разряде. Эти счетчики фиксируются во вспомогательном массиве счетчиков &amp;lt;tex&amp;gt;cnt&amp;lt;/tex&amp;gt;. Затем счетчики используются для вычисления размеров корзин и определения границ разделения массива. В соответствии с этими границами сортируемые объекты переносятся во вспомогательный массив &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, в котором размещены корзины.&lt;br /&gt;
После того как корзины сформированы, содержимое вспомогательного массива &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; переносится обратно в исходный массив &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и выполняется рекурсивное разделение новых частей по следующему разряду в пределах границ корзин, полученных на предыдущем шаге.&lt;br /&gt;
&lt;br /&gt;
Изначально запускаем функцию так &amp;lt;math&amp;gt;\mathrm{radixSort(A, 0, A.length - 1, 1)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  '''function''' radixSort(int[] A, int l, int r, int d):&lt;br /&gt;
      '''if''' d &amp;gt; m '''or''' l &amp;gt;= r &lt;br /&gt;
          '''return'''&lt;br /&gt;
      '''for''' j = 0 '''to''' k + 1 &lt;br /&gt;
          cnt[j] = 0&lt;br /&gt;
      '''for''' i = l '''to''' r                              &lt;br /&gt;
          j = digit(A[i], d)&lt;br /&gt;
          cnt[j + 1]++&lt;br /&gt;
      '''for''' j = 2 '''to''' k&lt;br /&gt;
          cnt[j] += cnt[j - 1]&lt;br /&gt;
      '''for''' i = l '''to''' r&lt;br /&gt;
          j = digit(A[i], d)&lt;br /&gt;
          c[l + cnt[j]] = A[i]&lt;br /&gt;
          cnt[j]--&lt;br /&gt;
      '''for''' i = l '''to''' r&lt;br /&gt;
          A[i] = c[i]&lt;br /&gt;
      radixSort(A, l, l + cnt[0] - 1, d + 1)&lt;br /&gt;
      '''for''' i = 1 '''to''' k&lt;br /&gt;
          radixSort(A, l + cnt[i - 1], l + cnt[i] - 1, d + 1)&lt;br /&gt;
&lt;br /&gt;
==Сложность==&lt;br /&gt;
===Сложность LSD-сортировки===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt; {{---}} количество разрядов, &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; {{---}} количество объектов, которые нужно отсортировать, &amp;lt;tex&amp;gt; T(n) &amp;lt;/tex&amp;gt; {{---}} время работы устойчивой сортировки. Цифровая сортировка выполняет &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt; итераций, на каждой из которой выполняется устойчивая сортировка и не более &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt; других операций. Следовательно время работы цифровой сортировки {{---}} &amp;lt;tex&amp;gt; O(k T(n)) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отдельно случай сортировки чисел. Пусть в качестве аргумента сортировке передается массив, в котором содержатся &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt;-значных чисел, и каждая цифра может принимать значения от &amp;lt;tex&amp;gt; 0 &amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt; k - 1 &amp;lt;/tex&amp;gt;. Тогда цифровая сортировка позволяет отсортировать данный массив за время &amp;lt;tex&amp;gt; O(m (n + k)) &amp;lt;/tex&amp;gt;, если устойчивая сортировка имеет время работы &amp;lt;tex&amp;gt; O(n + k) &amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt; небольшое, то оптимально выбирать в качестве устойчивой сортировки сортировку подсчетом.&lt;br /&gt;
&lt;br /&gt;
Если количество разрядов {{---}} константа, а &amp;lt;tex&amp;gt; k = O(n) &amp;lt;/tex&amp;gt;, то сложность цифровой сортировки составляет &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt;, то есть она линейно зависит от количества сортируемых чисел.&lt;br /&gt;
===Сложность MSD-сортировки===&lt;br /&gt;
Пусть значения разрядов меньше &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt;, а количество разрядов {{---}} &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. При сортировке массива из одинаковых элементов MSD-сортировкой на каждом шаге все элементы будут находится в неубывающей по размеру корзине, а так как цикл идет по всем элементам массива, то получим, что время работы MSD-сортировки оценивается величиной &amp;lt;tex&amp;gt;O(nk)&amp;lt;/tex&amp;gt;, причем это время нельзя улучшить. Хорошим случаем для данной сортировки будет массив, при котором на каждом шаге каждая корзина будет делиться на &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; частей. Как только размер корзины станет равен &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, сортировка перестанет рекурсивно запускаться в этой корзине. Таким образом, асимптотика будет &amp;lt;math&amp;gt;\Omega(n\log_b{n})&amp;lt;/math&amp;gt;. Это хорошо тем, что не зависит от числа разрядов.&lt;br /&gt;
&lt;br /&gt;
Существует также модификация MSD-сортировки, при которой рекурсивный процесс останавливается при небольших размерах текущего кармана, и вызывается более быстрая сортировка, основанная на сравнениях (например, сортировка вставками).&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Сортировка подсчетом]]&lt;br /&gt;
* [[Сортировка вставками]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:ru:Поразрядная сортировка|Википедия {{---}} Цифровая сортировка]]&lt;br /&gt;
* [http://rain.ifmo.ru/cat/view.php/vis/sorts/linear-2005 Визуализатор 1] — Java-аплет.&lt;br /&gt;
* [http://rain.ifmo.ru/cat/view.php/vis/sorts/linear-2001 Визуализатор 2] — Java-аплет.&lt;br /&gt;
* Дональд Кнут Искусство программирования, том 3. Сортировка и поиск&lt;br /&gt;
* Кормен, Т., Лейзерсон, Ч., Ривест, Р., Штайн, К. Алгоритмы: построение и анализ&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Сортировки]]&lt;br /&gt;
[[Категория: Другие сортировки]]&lt;/div&gt;</summary>
		<author><name>188.130.155.152</name></author>	</entry>

	</feed>