<?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=109.188.215.38&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=109.188.215.38&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/109.188.215.38"/>
		<updated>2026-04-15T13:56:55Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%A5%D0%B0%D0%BD%D0%B0&amp;diff=24886</id>
		<title>Сортировка Хана</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%A5%D0%B0%D0%BD%D0%B0&amp;diff=24886"/>
				<updated>2012-06-11T06:08:12Z</updated>
		
		<summary type="html">&lt;p&gt;109.188.215.38: автор либо весьма упоролся, либо не знал о \{, \}&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Сортировка Хана (Yijie Han)''' {{---}} сложный алгоритм сортировки целых чисел со сложностью &amp;lt;tex&amp;gt;O(n \log\log n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} количество элементов для сортировки.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Алгоритм построен на основе экспоненциального поискового дерева (далее {{---}} Э.П.дерево) Андерсона (Andersson's exponential search tree). Сортировка происходит за счет вставки целых чисел в Э.П.дерево.&lt;br /&gt;
&lt;br /&gt;
== Andersson's exponential search tree ==&lt;br /&gt;
Э.П.дерево с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; листьями состоит из корня &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;n^e&amp;lt;/tex&amp;gt; (0&amp;lt;&amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;&amp;lt;1) Э.П.поддеревьев, в каждом из которых &amp;lt;tex&amp;gt;n^{1 - e}&amp;lt;/tex&amp;gt; листьев; каждое Э.П.поддерево является сыном корня &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. В этом дереве &amp;lt;tex&amp;gt;O(n \log\log n)&amp;lt;/tex&amp;gt; уровней. При нарушении баланса дерева, необходимо балансирование, которое требует &amp;lt;tex&amp;gt;O(n \log\log n)&amp;lt;/tex&amp;gt; времени при &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вставленных целых числах. Такое время достигается за счет вставки чисел группами, а не по одиночке, как изначально предлагает Андерссон.&lt;br /&gt;
&lt;br /&gt;
==Необходимая информация==&lt;br /&gt;
{{Определение&lt;br /&gt;
|id=def1. &lt;br /&gt;
|definition=&lt;br /&gt;
Контейнер {{---}} объект определенного типа, содержащий обрабатываемый элемент. Например __int32, __int64, и т.д.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|id=def2. &lt;br /&gt;
|definition=&lt;br /&gt;
Алгоритм сортирующий &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; целых чисел из множества &amp;lt;tex&amp;gt;\{0, 1, \ldots, m - 1\}&amp;lt;/tex&amp;gt; называется консервативным, если длина контейнера (число бит в контейнере), является &amp;lt;tex&amp;gt;O(\log(m + n))&amp;lt;/tex&amp;gt;. Если длина больше, то алгоритм не консервативный.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|id=def3. &lt;br /&gt;
|definition=&lt;br /&gt;
Для множества &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; определим&lt;br /&gt;
min(&amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;) = min(&amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;:&amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; принадлежит &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;)&lt;br /&gt;
max(&amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;) = max(&amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;:&amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; принадлежит &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;)&lt;br /&gt;
Набор &amp;lt;tex&amp;gt;S1&amp;lt;/tex&amp;gt; &amp;lt; &amp;lt;tex&amp;gt;S2&amp;lt;/tex&amp;gt; если max(&amp;lt;tex&amp;gt;S1&amp;lt;/tex&amp;gt;) &amp;lt;= min(&amp;lt;tex&amp;gt;S2&amp;lt;/tex&amp;gt;)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Уменьшение числа бит в числах==&lt;br /&gt;
Один из способов ускорить сортировку {{---}} уменьшить число бит в числе. Один из способов уменьшить число бит в числе {{---}} использовать деление пополам (эту идею впервые подал van Emde Boas). Деление пополам заключается в том, что количество оставшихся бит в числе уменьшается в 2 раза. Это быстрый способ, требующий &amp;lt;tex&amp;gt;O(m)&amp;lt;/tex&amp;gt; памяти. Для своего дерева Андерссон использует хеширование, что позволяет сократить количество памяти до &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;. Для того, чтобы еще ускорить алгоритм нам необходимо упаковать несколько чисел в один контейнер, чтобы затем за константное количество шагов произвести хэширование для всех чисел хранимых в контейнере. Для этого используется хэш функция для хэширования &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; чисел в таблицу размера &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt; за константное время, без коллизий. Для этого используется хэш модифицированная функция авторства: Dierzfelbinger и Raman.&lt;br /&gt;
&lt;br /&gt;
Алгоритм: Пусть целое число &amp;lt;tex&amp;gt;b &amp;gt;= 0&amp;lt;/tex&amp;gt; и пусть &amp;lt;tex&amp;gt;U = \{0, \ldots, 2^b - 1\}&amp;lt;/tex&amp;gt;. Класс &amp;lt;tex&amp;gt;H_{b,s}&amp;lt;/tex&amp;gt; хэш функций из &amp;lt;tex&amp;gt;U&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\{0, \ldots, 2^s - 1\}&amp;lt;/tex&amp;gt; определен как &amp;lt;tex&amp;gt;H_{b,s} = \{h_{a} \mid 0 &amp;lt; a &amp;lt; 2^b, a \equiv 1 (\mod 2)\}&amp;lt;/tex&amp;gt; и для всех &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;U: h_{a}(x) = (ax \mod 2^b) div 2^{b - s}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм базируется на следующей лемме:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1. &lt;br /&gt;
|statement=&lt;br /&gt;
Даны целые числа &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; &amp;gt;= &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; &amp;gt;= 0 и &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; является подмножеством {0, ..., &amp;lt;tex&amp;gt;2^b&amp;lt;/tex&amp;gt; - 1}, содержащим &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; элементов, и &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; &amp;gt;= &amp;lt;tex&amp;gt;2^{-s + 1}&amp;lt;/tex&amp;gt;С&amp;lt;tex&amp;gt;^k_{n}&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;h_{a}&amp;lt;/tex&amp;gt; принадлежащая &amp;lt;tex&amp;gt;H_{b,s}&amp;lt;/tex&amp;gt; может быть выбрана за время &amp;lt;tex&amp;gt;O(bn^2)&amp;lt;/tex&amp;gt; так, что количество коллизий &amp;lt;tex&amp;gt;coll(h_{a}, T) &amp;lt;= t&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Взяв &amp;lt;tex&amp;gt;s = 2logn&amp;lt;/tex&amp;gt; мы получим хэш функцию &amp;lt;tex&amp;gt;h_{a}&amp;lt;/tex&amp;gt; которая захэширует &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; чисел из &amp;lt;tex&amp;gt;U&amp;lt;/tex&amp;gt; в таблицу размера &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt; без коллизий. Очевидно, что &amp;lt;tex&amp;gt;h_{a}(x)&amp;lt;/tex&amp;gt; может быть посчитана для любого &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; за константное время. Если мы упакуем несколько чисел в один контейнер так, что они разделены несколькими битами нулей, мы спокойно сможем применить &amp;lt;tex&amp;gt;h_{a}&amp;lt;/tex&amp;gt; ко всему контейнеру, а в результате все хэш значения для всех чисел в контейере были посчитаны. Заметим, что это возможно только потому, что в вычисление хэш знчения вовлечены только (mod &amp;lt;tex&amp;gt;2^b&amp;lt;/tex&amp;gt;) и (div &amp;lt;tex&amp;gt;2^{b - s}&amp;lt;/tex&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Такая хэш функция может быть найдена за &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Следует отметить, что несмотря на размер таблицы &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;, потребность в памяти не превышает &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; потому, что хэширование используется только для уменьшения количества бит в числе.&lt;br /&gt;
&lt;br /&gt;
==Signature sorting==&lt;br /&gt;
В данной сортировке используется следующий алгоритм:&lt;br /&gt;
&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; чисел должны быть сортированы, и в каждом &amp;lt;tex&amp;gt;logm&amp;lt;/tex&amp;gt; бит. Мы рассматриваем, что в каждом числе есть &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; сегментов, в каждом из которых &amp;lt;tex&amp;gt;log(m/h)&amp;lt;/tex&amp;gt; бит. Теперь мы применяем хэширование ко всем сегментам и получаем &amp;lt;tex&amp;gt;2hlogn&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;n&amp;lt;/tex&amp;gt; чисел по &amp;lt;tex&amp;gt;log(m/h)&amp;lt;/tex&amp;gt; бит в каждом.&lt;br /&gt;
&lt;br /&gt;
Так же, рассмотрим проблему последующего разделения. Пусть &amp;lt;tex&amp;gt;a_{1}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;a_{2}&amp;lt;/tex&amp;gt;, ..., &amp;lt;tex&amp;gt;a_{p}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; чисел и &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; {{---}} множество чисeл. Мы хотим разделить &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;p + 1&amp;lt;/tex&amp;gt; наборов таких, что: &amp;lt;tex&amp;gt;S_{0}&amp;lt;/tex&amp;gt; &amp;lt; {&amp;lt;tex&amp;gt;a_{1}&amp;lt;/tex&amp;gt;} &amp;lt; &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; &amp;lt; {&amp;lt;tex&amp;gt;a_{2}&amp;lt;/tex&amp;gt;} &amp;lt; ... &amp;lt; {&amp;lt;tex&amp;gt;a_{p}&amp;lt;/tex&amp;gt;} &amp;lt; &amp;lt;tex&amp;gt;S_{p}&amp;lt;/tex&amp;gt;. Т.к. мы используем signature sorting, до того как делать вышеописанное разделение, мы поделим биты в &amp;lt;tex&amp;gt;a_{i}&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; сегментов и возьмем некоторые из них. Мы так же поделим биты для каждого числа из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и оставим только один в каждом числе. По существу для каждого &amp;lt;tex&amp;gt;a_{i}&amp;lt;/tex&amp;gt; мы возьмем все &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; сегментов. Если соответствующие сегменты &amp;lt;tex&amp;gt;a_{i}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;a_{j}&amp;lt;/tex&amp;gt; совпадают, то нам понадобится только один. Сегменты, которые мы берем для числа в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, {{---}} сегмент, который &amp;quot;вылетает&amp;quot; из &amp;lt;tex&amp;gt;a_{i}&amp;lt;/tex&amp;gt;. Таким образом мы преобразуем начальную задачу о разделении &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; чисел в &amp;lt;tex&amp;gt;logm&amp;lt;/tex&amp;gt; бит в несколько задач на разделение с числами в &amp;lt;tex&amp;gt;log(m/h)&amp;lt;/tex&amp;gt; бит.&lt;/div&gt;</summary>
		<author><name>109.188.215.38</name></author>	</entry>

	</feed>