<?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=KKutirev</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=KKutirev"/>
		<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/KKutirev"/>
		<updated>2026-05-19T14:02:20Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33994</id>
		<title>Алгоритм Хаффмана</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33994"/>
				<updated>2013-12-09T16:05:34Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: /* Время работы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''''Алгоритм Хаффмана''''' — алгоритм оптимального префиксного кодирования алфавита. Был разработан в 1952 году аспирантом Массачусетского технологического института Дэвидом Хаффманом при написании им курсовой работы. Используется во многих программах сжатия данных, например, PKZIP 2, LZH и др.&lt;br /&gt;
&lt;br /&gt;
== Определение ==&lt;br /&gt;
&lt;br /&gt;
{{Определение &lt;br /&gt;
|definition=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;W=\{w_{1},w_{2},...,w_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Тогда набор бинарных кодов &amp;lt;tex&amp;gt;C=\{c_{1},c_{2},...,c_{n}\}&amp;lt;/tex&amp;gt;, такой, что:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;gt; не является префиксом для &amp;lt;tex&amp;gt;c_{j}&amp;lt;/tex&amp;gt;, при &amp;lt;tex&amp;gt;i \ne j&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Сумма &amp;lt;tex&amp;gt;\sum\limits_{i \in [1, n]} w_{i}\cdot c_{i}&amp;lt;/tex&amp;gt; минимальна. (&amp;lt;tex&amp;gt;|c_{i}|&amp;lt;/tex&amp;gt; — длина кода &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;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;
1. Составим [[Список | список]] кодируемых символов, при этом будем рассматривать один символ как дерево, состоящее из одного элемента, весом, равным частоте появления символа в тексте.&lt;br /&gt;
&lt;br /&gt;
2. Из списка выберем два узла с наименьшим весом.&lt;br /&gt;
&lt;br /&gt;
3. Сформируем новый узел с весом, равным сумме весов выбранных узлов, и присоединим к нему два выбранных узла в качестве дочерних.&lt;br /&gt;
&lt;br /&gt;
4. Добавим к списку только что сформированный узел.&lt;br /&gt;
&lt;br /&gt;
5. Если в списке больше одного узла, то повторить пункты со второго по пятый.&lt;br /&gt;
&lt;br /&gt;
== Время работы ==&lt;br /&gt;
Если сортировать элементы после каждого суммирования или использовать очередь с приоритетами, то алгоритм будет работать за время &amp;lt;tex&amp;gt;O(NlogN)&amp;lt;/tex&amp;gt;.Такую асимптотику можно улучшить до &amp;lt;tex&amp;gt;O(N)&amp;lt;/tex&amp;gt;, используя обычные массивы.&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Mississippi.png|400px|thumb|right|Дерево Хаффмана для слова ''&amp;quot;Миссисипи&amp;quot;'']]&lt;br /&gt;
&lt;br /&gt;
Для примера возьмём слово ''&amp;quot;Миссисипи&amp;quot;''. Тогда алфавит будет &amp;lt;tex&amp;gt;A= \{&amp;lt;/tex&amp;gt; ''и, м, п, с'' &amp;lt;tex&amp;gt;\} &amp;lt;/tex&amp;gt;, а набор весов &amp;lt;tex&amp;gt;W=\{4, 1, 1, 3\}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 1 || 1 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
По алгоритму возьмем два символа с наименьшей частотой {{---}} это ''м'' и ''п''. Сформируем из них новый узел ''мп'' весом 2 и добавим его к списку узлов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мп || с &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 2 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Затем объединим в один узел узлы ''мп'' и ''c'':&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мпс &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 5 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
И, наконец, объединяем два узла ''и'' и ''мпс''. Итак, мы получили дерево Хаффмана и соответствующую ему таблицу кодов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Код || 0 || 100 || 101 || 11&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, закодированное слово ''&amp;quot;миссисипи&amp;quot;'' будет выглядеть как ''&amp;quot;1000111101101010&amp;quot;''. Длина закодированного слова {{---}} 16 бит. Стоит заметить, что если бы мы использовали для кодирования каждого символа из четырёх по 2 бита, длина закодированного слова составила бы 18 бит.&lt;br /&gt;
&lt;br /&gt;
== Корректность алгоритма Хаффмана ==&lt;br /&gt;
 &lt;br /&gt;
Чтобы доказать корректность алгоритма Хаффмана, покажем, что в [[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | задаче о построении оптимального префиксного кода]] проявляются свойства жадного выбора и оптимальной подструктуры. В сформулированной ниже лемме показано соблюдение свойства жадного выбора. &lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; — алфавит, каждый символ &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; которого встречается с частотой &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с самыми низкими частотами.&lt;br /&gt;
&lt;br /&gt;
Тогда для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; существует оптимальный префиксный код, кодовые слова символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; в котором имеют одинаковую максимальную длину и отличаются лишь последним битом. &lt;br /&gt;
|proof=&lt;br /&gt;
Возьмем дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, представляющее произвольный оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Преобразуем его в дерево, представляющее другой оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — листья с общим родительским узлом, находящиеся на максимальной глубине.&lt;br /&gt;
&lt;br /&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;T&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;f[a] \le f[b]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[x] \le f[y]&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y]&amp;lt;/tex&amp;gt; — две наименьшие частоты, а &amp;lt;tex&amp;gt;f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[b]&amp;lt;/tex&amp;gt; — две произвольные частоты, то выполняются отношения &amp;lt;tex&amp;gt;f[x] \le f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y] \le f[b]&amp;lt;/tex&amp;gt;. Пусть дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — дерево, полученное из &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; путем перестановки листьев &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, а дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево полученное из &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; перестановкой листьев &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Разность стоимостей деревьев &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; равна:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T) - B(T') = \sum\limits_{c \in C} f(c)d_T(c) - \sum\limits_{c \in C} f(c)d_{T'}(c) = (f[a] - f[x])(d_T(a) - d_T(x)),&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
что больше либо равно &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, так как величины &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; неотрицательны. Величина &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; неотрицательна, потому что &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — лист с минимальной частотой, а величина &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; является неотрицательной, так как лист &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; находится на максимальной глубине в дереве &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Точно так же перестановка листьев &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; не будет приводить к увеличению стоимости. Таким образом, разность &amp;lt;tex&amp;gt;B(T') - B(T'')&amp;lt;/tex&amp;gt; тоже будет неотрицательной.&lt;br /&gt;
&lt;br /&gt;
Таким образом, выполняется неравенство &amp;lt;tex&amp;gt;B(T'') \le B(T)&amp;lt;/tex&amp;gt;. С другой стороны, &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; — оптимальное дерево, поэтому должно выполняться неравенство &amp;lt;tex&amp;gt;B(T) \le B(T'')&amp;lt;/tex&amp;gt;. Отсюда следует, что &amp;lt;tex&amp;gt;B(T) = B(T'')&amp;lt;/tex&amp;gt;. Значит, &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево, представляющее оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; имеют одинаковую максимальную длину, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
 &lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=Пусть дан алфавит &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, в котором для каждого символа &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; определены частоты &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с минимальными частотами. Пусть &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; — алфавит, полученный из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; путем удаления символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и добавления нового символа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;, так что &amp;lt;tex&amp;gt;C' = C \backslash \{ x, y \} \cup {z}&amp;lt;/tex&amp;gt;. По определению частоты &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; в алфавите &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; совпадают с частотами в алфавите &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, за исключением частоты &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — произвольное дерево, представляющее оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; Тогда дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, полученное из дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; путем замены листа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; внутренним узлом с дочерними элементами &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof=&lt;br /&gt;
Сначала покажем, что стоимость &amp;lt;tex&amp;gt;B(T)&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; может быть выражена через стоимость &amp;lt;tex&amp;gt;B(T')&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt;. Для каждого символа &amp;lt;tex&amp;gt;c \in C \backslash \{x, y \}&amp;lt;/tex&amp;gt; верно &amp;lt;tex&amp;gt;d_T(C) = d_{T'}&amp;lt;/tex&amp;gt;, значит, &amp;lt;tex&amp;gt;f[c]d_T(c) = f[c]d_{T'}(c)&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;d_T(x) = d_T(y) = d_{T'} (z) + 1&amp;lt;/tex&amp;gt;, то&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f[x]d_T(x) + f[y]d_T(y) = (f[x] + f[y])(d_{T'}(z) + 1) = f[z]d_{T'}(z) + (f[x] + f[y])&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
из чего следует, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T) = B(T') + f[x] + f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T') = B(T) - f[x] - f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем лемму от противного. Предположим, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Тогда существует дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;B(T'') &amp;lt; B(T)&amp;lt;/tex&amp;gt;. Согласно лемме (1), элементы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; можно считать дочерними элементами одного узла. Пусть дерево &amp;lt;tex&amp;gt;T'''&amp;lt;/tex&amp;gt; получено из дерева &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; заменой элементов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; листом &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; с частотой &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Тогда&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T''') = B(T'') - f[x] - f[y] &amp;lt; B(T) - f[x] - f[y] = B(T')&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
что противоречит предположению о том, что дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt;. Значит, наше предположение о том, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, неверно, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Алгоритм Хаффмана дает оптимальный префиксный код. &lt;br /&gt;
|proof=&lt;br /&gt;
Справедливость теоремы непосредственно следует из лемм (1) и (2)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — с. 459. — ISBN 5-8489-0857-4&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Алгоритм_Хаффмана Википедия — Алгоритм Хаффмана]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Wikipedia — Huffman coding]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%C4%E2%EE%E8%F7%ED%EE%E5_%E4%E5%F0%E5%E2%EE Википедия — Бинарное дерево]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Префиксный_код Википедия — Префиксный код]&lt;br /&gt;
*[[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | Задача об оптимальном префиксном коде]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33993</id>
		<title>Алгоритм Хаффмана</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33993"/>
				<updated>2013-12-09T16:02:12Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: /* Корректность алгоритма Хаффмана */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''''Алгоритм Хаффмана''''' — алгоритм оптимального префиксного кодирования алфавита. Был разработан в 1952 году аспирантом Массачусетского технологического института Дэвидом Хаффманом при написании им курсовой работы. Используется во многих программах сжатия данных, например, PKZIP 2, LZH и др.&lt;br /&gt;
&lt;br /&gt;
== Определение ==&lt;br /&gt;
&lt;br /&gt;
{{Определение &lt;br /&gt;
|definition=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;W=\{w_{1},w_{2},...,w_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Тогда набор бинарных кодов &amp;lt;tex&amp;gt;C=\{c_{1},c_{2},...,c_{n}\}&amp;lt;/tex&amp;gt;, такой, что:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;gt; не является префиксом для &amp;lt;tex&amp;gt;c_{j}&amp;lt;/tex&amp;gt;, при &amp;lt;tex&amp;gt;i \ne j&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Сумма &amp;lt;tex&amp;gt;\sum\limits_{i \in [1, n]} w_{i}\cdot c_{i}&amp;lt;/tex&amp;gt; минимальна. (&amp;lt;tex&amp;gt;|c_{i}|&amp;lt;/tex&amp;gt; — длина кода &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;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;
1. Составим [[Список | список]] кодируемых символов, при этом будем рассматривать один символ как дерево, состоящее из одного элемента, весом, равным частоте появления символа в тексте.&lt;br /&gt;
&lt;br /&gt;
2. Из списка выберем два узла с наименьшим весом.&lt;br /&gt;
&lt;br /&gt;
3. Сформируем новый узел с весом, равным сумме весов выбранных узлов, и присоединим к нему два выбранных узла в качестве дочерних.&lt;br /&gt;
&lt;br /&gt;
4. Добавим к списку только что сформированный узел.&lt;br /&gt;
&lt;br /&gt;
5. Если в списке больше одного узла, то повторить пункты со второго по пятый.&lt;br /&gt;
&lt;br /&gt;
== Время работы ==&lt;br /&gt;
Если сортировать элементы после каждого суммирования или использовать очередь с приоритетами, то алгоритм будет работать за время &amp;lt;tex&amp;gt;O(NlogN)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Mississippi.png|400px|thumb|right|Дерево Хаффмана для слова ''&amp;quot;Миссисипи&amp;quot;'']]&lt;br /&gt;
&lt;br /&gt;
Для примера возьмём слово ''&amp;quot;Миссисипи&amp;quot;''. Тогда алфавит будет &amp;lt;tex&amp;gt;A= \{&amp;lt;/tex&amp;gt; ''и, м, п, с'' &amp;lt;tex&amp;gt;\} &amp;lt;/tex&amp;gt;, а набор весов &amp;lt;tex&amp;gt;W=\{4, 1, 1, 3\}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 1 || 1 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
По алгоритму возьмем два символа с наименьшей частотой {{---}} это ''м'' и ''п''. Сформируем из них новый узел ''мп'' весом 2 и добавим его к списку узлов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мп || с &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 2 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Затем объединим в один узел узлы ''мп'' и ''c'':&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мпс &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 5 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
И, наконец, объединяем два узла ''и'' и ''мпс''. Итак, мы получили дерево Хаффмана и соответствующую ему таблицу кодов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Код || 0 || 100 || 101 || 11&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, закодированное слово ''&amp;quot;миссисипи&amp;quot;'' будет выглядеть как ''&amp;quot;1000111101101010&amp;quot;''. Длина закодированного слова {{---}} 16 бит. Стоит заметить, что если бы мы использовали для кодирования каждого символа из четырёх по 2 бита, длина закодированного слова составила бы 18 бит.&lt;br /&gt;
&lt;br /&gt;
== Корректность алгоритма Хаффмана ==&lt;br /&gt;
 &lt;br /&gt;
Чтобы доказать корректность алгоритма Хаффмана, покажем, что в [[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | задаче о построении оптимального префиксного кода]] проявляются свойства жадного выбора и оптимальной подструктуры. В сформулированной ниже лемме показано соблюдение свойства жадного выбора. &lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; — алфавит, каждый символ &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; которого встречается с частотой &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с самыми низкими частотами.&lt;br /&gt;
&lt;br /&gt;
Тогда для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; существует оптимальный префиксный код, кодовые слова символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; в котором имеют одинаковую максимальную длину и отличаются лишь последним битом. &lt;br /&gt;
|proof=&lt;br /&gt;
Возьмем дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, представляющее произвольный оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Преобразуем его в дерево, представляющее другой оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — листья с общим родительским узлом, находящиеся на максимальной глубине.&lt;br /&gt;
&lt;br /&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;T&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;f[a] \le f[b]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[x] \le f[y]&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y]&amp;lt;/tex&amp;gt; — две наименьшие частоты, а &amp;lt;tex&amp;gt;f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[b]&amp;lt;/tex&amp;gt; — две произвольные частоты, то выполняются отношения &amp;lt;tex&amp;gt;f[x] \le f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y] \le f[b]&amp;lt;/tex&amp;gt;. Пусть дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — дерево, полученное из &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; путем перестановки листьев &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, а дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево полученное из &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; перестановкой листьев &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Разность стоимостей деревьев &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; равна:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T) - B(T') = \sum\limits_{c \in C} f(c)d_T(c) - \sum\limits_{c \in C} f(c)d_{T'}(c) = (f[a] - f[x])(d_T(a) - d_T(x)),&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
что больше либо равно &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, так как величины &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; неотрицательны. Величина &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; неотрицательна, потому что &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — лист с минимальной частотой, а величина &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; является неотрицательной, так как лист &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; находится на максимальной глубине в дереве &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Точно так же перестановка листьев &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; не будет приводить к увеличению стоимости. Таким образом, разность &amp;lt;tex&amp;gt;B(T') - B(T'')&amp;lt;/tex&amp;gt; тоже будет неотрицательной.&lt;br /&gt;
&lt;br /&gt;
Таким образом, выполняется неравенство &amp;lt;tex&amp;gt;B(T'') \le B(T)&amp;lt;/tex&amp;gt;. С другой стороны, &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; — оптимальное дерево, поэтому должно выполняться неравенство &amp;lt;tex&amp;gt;B(T) \le B(T'')&amp;lt;/tex&amp;gt;. Отсюда следует, что &amp;lt;tex&amp;gt;B(T) = B(T'')&amp;lt;/tex&amp;gt;. Значит, &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево, представляющее оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; имеют одинаковую максимальную длину, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
 &lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=Пусть дан алфавит &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, в котором для каждого символа &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; определены частоты &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с минимальными частотами. Пусть &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; — алфавит, полученный из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; путем удаления символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и добавления нового символа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;, так что &amp;lt;tex&amp;gt;C' = C \backslash \{ x, y \} \cup {z}&amp;lt;/tex&amp;gt;. По определению частоты &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; в алфавите &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; совпадают с частотами в алфавите &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, за исключением частоты &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — произвольное дерево, представляющее оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; Тогда дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, полученное из дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; путем замены листа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; внутренним узлом с дочерними элементами &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof=&lt;br /&gt;
Сначала покажем, что стоимость &amp;lt;tex&amp;gt;B(T)&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; может быть выражена через стоимость &amp;lt;tex&amp;gt;B(T')&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt;. Для каждого символа &amp;lt;tex&amp;gt;c \in C \backslash \{x, y \}&amp;lt;/tex&amp;gt; верно &amp;lt;tex&amp;gt;d_T(C) = d_{T'}&amp;lt;/tex&amp;gt;, значит, &amp;lt;tex&amp;gt;f[c]d_T(c) = f[c]d_{T'}(c)&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;d_T(x) = d_T(y) = d_{T'} (z) + 1&amp;lt;/tex&amp;gt;, то&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f[x]d_T(x) + f[y]d_T(y) = (f[x] + f[y])(d_{T'}(z) + 1) = f[z]d_{T'}(z) + (f[x] + f[y])&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
из чего следует, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T) = B(T') + f[x] + f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T') = B(T) - f[x] - f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем лемму от противного. Предположим, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Тогда существует дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;B(T'') &amp;lt; B(T)&amp;lt;/tex&amp;gt;. Согласно лемме (1), элементы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; можно считать дочерними элементами одного узла. Пусть дерево &amp;lt;tex&amp;gt;T'''&amp;lt;/tex&amp;gt; получено из дерева &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; заменой элементов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; листом &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; с частотой &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Тогда&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T''') = B(T'') - f[x] - f[y] &amp;lt; B(T) - f[x] - f[y] = B(T')&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
что противоречит предположению о том, что дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt;. Значит, наше предположение о том, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, неверно, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Алгоритм Хаффмана дает оптимальный префиксный код. &lt;br /&gt;
|proof=&lt;br /&gt;
Справедливость теоремы непосредственно следует из лемм (1) и (2)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — с. 459. — ISBN 5-8489-0857-4&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Алгоритм_Хаффмана Википедия — Алгоритм Хаффмана]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Wikipedia — Huffman coding]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%C4%E2%EE%E8%F7%ED%EE%E5_%E4%E5%F0%E5%E2%EE Википедия — Бинарное дерево]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Префиксный_код Википедия — Префиксный код]&lt;br /&gt;
*[[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | Задача об оптимальном префиксном коде]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33992</id>
		<title>Алгоритм Хаффмана</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33992"/>
				<updated>2013-12-09T16:01:02Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''''Алгоритм Хаффмана''''' — алгоритм оптимального префиксного кодирования алфавита. Был разработан в 1952 году аспирантом Массачусетского технологического института Дэвидом Хаффманом при написании им курсовой работы. Используется во многих программах сжатия данных, например, PKZIP 2, LZH и др.&lt;br /&gt;
&lt;br /&gt;
== Определение ==&lt;br /&gt;
&lt;br /&gt;
{{Определение &lt;br /&gt;
|definition=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;W=\{w_{1},w_{2},...,w_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Тогда набор бинарных кодов &amp;lt;tex&amp;gt;C=\{c_{1},c_{2},...,c_{n}\}&amp;lt;/tex&amp;gt;, такой, что:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;gt; не является префиксом для &amp;lt;tex&amp;gt;c_{j}&amp;lt;/tex&amp;gt;, при &amp;lt;tex&amp;gt;i \ne j&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Сумма &amp;lt;tex&amp;gt;\sum\limits_{i \in [1, n]} w_{i}\cdot c_{i}&amp;lt;/tex&amp;gt; минимальна. (&amp;lt;tex&amp;gt;|c_{i}|&amp;lt;/tex&amp;gt; — длина кода &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;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;
1. Составим [[Список | список]] кодируемых символов, при этом будем рассматривать один символ как дерево, состоящее из одного элемента, весом, равным частоте появления символа в тексте.&lt;br /&gt;
&lt;br /&gt;
2. Из списка выберем два узла с наименьшим весом.&lt;br /&gt;
&lt;br /&gt;
3. Сформируем новый узел с весом, равным сумме весов выбранных узлов, и присоединим к нему два выбранных узла в качестве дочерних.&lt;br /&gt;
&lt;br /&gt;
4. Добавим к списку только что сформированный узел.&lt;br /&gt;
&lt;br /&gt;
5. Если в списке больше одного узла, то повторить пункты со второго по пятый.&lt;br /&gt;
&lt;br /&gt;
== Время работы ==&lt;br /&gt;
Если сортировать элементы после каждого суммирования или использовать очередь с приоритетами, то алгоритм будет работать за время &amp;lt;tex&amp;gt;O(NlogN)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Mississippi.png|400px|thumb|right|Дерево Хаффмана для слова ''&amp;quot;Миссисипи&amp;quot;'']]&lt;br /&gt;
&lt;br /&gt;
Для примера возьмём слово ''&amp;quot;Миссисипи&amp;quot;''. Тогда алфавит будет &amp;lt;tex&amp;gt;A= \{&amp;lt;/tex&amp;gt; ''и, м, п, с'' &amp;lt;tex&amp;gt;\} &amp;lt;/tex&amp;gt;, а набор весов &amp;lt;tex&amp;gt;W=\{4, 1, 1, 3\}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 1 || 1 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
По алгоритму возьмем два символа с наименьшей частотой {{---}} это ''м'' и ''п''. Сформируем из них новый узел ''мп'' весом 2 и добавим его к списку узлов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мп || с &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 2 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Затем объединим в один узел узлы ''мп'' и ''c'':&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мпс &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 5 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
И, наконец, объединяем два узла ''и'' и ''мпс''. Итак, мы получили дерево Хаффмана и соответствующую ему таблицу кодов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Код || 0 || 100 || 101 || 11&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, закодированное слово ''&amp;quot;миссисипи&amp;quot;'' будет выглядеть как ''&amp;quot;1000111101101010&amp;quot;''. Длина закодированного слова {{---}} 16 бит. Стоит заметить, что если бы мы использовали для кодирования каждого символа из четырёх по 2 бита, длина закодированного слова составила бы 18 бит.&lt;br /&gt;
&lt;br /&gt;
== Корректность алгоритма Хаффмана ==&lt;br /&gt;
 &lt;br /&gt;
Чтобы доказать корректность алгоритма Хаффмана, покажем, что в задаче о построении оптимального префиксного кода проявляются свойства жадного выбора и оптимальной подструктуры. В сформулированной ниже лемме показано соблюдение свойства жадного выбора. &lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; — алфавит, каждый символ &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; которого встречается с частотой &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с самыми низкими частотами.&lt;br /&gt;
&lt;br /&gt;
Тогда для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; существует оптимальный префиксный код, кодовые слова символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; в котором имеют одинаковую максимальную длину и отличаются лишь последним битом. &lt;br /&gt;
|proof=&lt;br /&gt;
Возьмем дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, представляющее произвольный оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Преобразуем его в дерево, представляющее другой оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — листья с общим родительским узлом, находящиеся на максимальной глубине.&lt;br /&gt;
&lt;br /&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;T&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;f[a] \le f[b]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[x] \le f[y]&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y]&amp;lt;/tex&amp;gt; — две наименьшие частоты, а &amp;lt;tex&amp;gt;f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[b]&amp;lt;/tex&amp;gt; — две произвольные частоты, то выполняются отношения &amp;lt;tex&amp;gt;f[x] \le f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y] \le f[b]&amp;lt;/tex&amp;gt;. Пусть дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — дерево, полученное из &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; путем перестановки листьев &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, а дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево полученное из &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; перестановкой листьев &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Разность стоимостей деревьев &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; равна:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T) - B(T') = \sum\limits_{c \in C} f(c)d_T(c) - \sum\limits_{c \in C} f(c)d_{T'}(c) = (f[a] - f[x])(d_T(a) - d_T(x)),&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
что больше либо равно &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, так как величины &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; неотрицательны. Величина &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; неотрицательна, потому что &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — лист с минимальной частотой, а величина &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; является неотрицательной, так как лист &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; находится на максимальной глубине в дереве &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Точно так же перестановка листьев &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; не будет приводить к увеличению стоимости. Таким образом, разность &amp;lt;tex&amp;gt;B(T') - B(T'')&amp;lt;/tex&amp;gt; тоже будет неотрицательной.&lt;br /&gt;
&lt;br /&gt;
Таким образом, выполняется неравенство &amp;lt;tex&amp;gt;B(T'') \le B(T)&amp;lt;/tex&amp;gt;. С другой стороны, &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; — оптимальное дерево, поэтому должно выполняться неравенство &amp;lt;tex&amp;gt;B(T) \le B(T'')&amp;lt;/tex&amp;gt;. Отсюда следует, что &amp;lt;tex&amp;gt;B(T) = B(T'')&amp;lt;/tex&amp;gt;. Значит, &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево, представляющее оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; имеют одинаковую максимальную длину, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
 &lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=Пусть дан алфавит &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, в котором для каждого символа &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; определены частоты &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с минимальными частотами. Пусть &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; — алфавит, полученный из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; путем удаления символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и добавления нового символа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;, так что &amp;lt;tex&amp;gt;C' = C \backslash \{ x, y \} \cup {z}&amp;lt;/tex&amp;gt;. По определению частоты &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; в алфавите &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; совпадают с частотами в алфавите &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, за исключением частоты &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — произвольное дерево, представляющее оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; Тогда дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, полученное из дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; путем замены листа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; внутренним узлом с дочерними элементами &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof=&lt;br /&gt;
Сначала покажем, что стоимость &amp;lt;tex&amp;gt;B(T)&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; может быть выражена через стоимость &amp;lt;tex&amp;gt;B(T')&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt;. Для каждого символа &amp;lt;tex&amp;gt;c \in C \backslash \{x, y \}&amp;lt;/tex&amp;gt; верно &amp;lt;tex&amp;gt;d_T(C) = d_{T'}&amp;lt;/tex&amp;gt;, значит, &amp;lt;tex&amp;gt;f[c]d_T(c) = f[c]d_{T'}(c)&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;d_T(x) = d_T(y) = d_{T'} (z) + 1&amp;lt;/tex&amp;gt;, то&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f[x]d_T(x) + f[y]d_T(y) = (f[x] + f[y])(d_{T'}(z) + 1) = f[z]d_{T'}(z) + (f[x] + f[y])&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
из чего следует, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T) = B(T') + f[x] + f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T') = B(T) - f[x] - f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем лемму от противного. Предположим, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Тогда существует дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;B(T'') &amp;lt; B(T)&amp;lt;/tex&amp;gt;. Согласно лемме (1), элементы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; можно считать дочерними элементами одного узла. Пусть дерево &amp;lt;tex&amp;gt;T'''&amp;lt;/tex&amp;gt; получено из дерева &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; заменой элементов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; листом &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; с частотой &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Тогда&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T''') = B(T'') - f[x] - f[y] &amp;lt; B(T) - f[x] - f[y] = B(T')&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
что противоречит предположению о том, что дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt;. Значит, наше предположение о том, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, неверно, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Алгоритм Хаффмана дает оптимальный префиксный код. &lt;br /&gt;
|proof=&lt;br /&gt;
Справедливость теоремы непосредственно следует из лемм (1) и (2)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — с. 459. — ISBN 5-8489-0857-4&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Алгоритм_Хаффмана Википедия — Алгоритм Хаффмана]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Wikipedia — Huffman coding]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%C4%E2%EE%E8%F7%ED%EE%E5_%E4%E5%F0%E5%E2%EE Википедия — Бинарное дерево]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Префиксный_код Википедия — Префиксный код]&lt;br /&gt;
*[[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | Задача об оптимальном префиксном коде]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33991</id>
		<title>Алгоритм Хаффмана</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33991"/>
				<updated>2013-12-09T15:46:51Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: /* Время работы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''''Алгоритм Хаффмана''''' — алгоритм оптимального префиксного кодирования алфавита. Был разработан в 1952 году аспирантом Массачусетского технологического института Дэвидом Хаффманом при написании им курсовой работы. Используется во многих программах сжатия данных, например, PKZIP 2, LZH и др.&lt;br /&gt;
&lt;br /&gt;
== Определение ==&lt;br /&gt;
&lt;br /&gt;
{{Определение &lt;br /&gt;
|definition=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;W=\{w_{1},w_{2},...,w_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Тогда набор бинарных кодов &amp;lt;tex&amp;gt;C=\{c_{1},c_{2},...,c_{n}\}&amp;lt;/tex&amp;gt;, такой, что:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;gt; не является префиксом для &amp;lt;tex&amp;gt;c_{j}&amp;lt;/tex&amp;gt;, при &amp;lt;tex&amp;gt;i \ne j&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Сумма &amp;lt;tex&amp;gt;\sum\limits_{i \in [1, n]} w_{i}\cdot c_{i}&amp;lt;/tex&amp;gt; минимальна. (&amp;lt;tex&amp;gt;|c_{i}|&amp;lt;/tex&amp;gt; — длина кода &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;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;
1. Составим [[Список | список]] кодируемых символов, при этом будем рассматривать один символ как дерево, состоящее из одного элемента, весом, равным частоте появления символа в тексте.&lt;br /&gt;
&lt;br /&gt;
2. Из списка выберем два узла с наименьшим весом.&lt;br /&gt;
&lt;br /&gt;
3. Сформируем новый узел с весом, равным сумме весов выбранных узлов, и присоединим к нему два выбранных узла в качестве дочерних.&lt;br /&gt;
&lt;br /&gt;
4. Добавим к списку только что сформированный узел.&lt;br /&gt;
&lt;br /&gt;
5. Если в списке больше одного узла, то повторить пункты со второго по пятый.&lt;br /&gt;
&lt;br /&gt;
== Время работы ==&lt;br /&gt;
Если сортировать элементы после каждого суммирования или использовать очередь с приоритетами, то алгоритм будет работать за время &amp;lt;tex&amp;gt;O(NlogN)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Mississippi.png|400px|thumb|right|Дерево Хаффмана для слова ''&amp;quot;Миссисипи&amp;quot;'']]&lt;br /&gt;
&lt;br /&gt;
Для примера возьмём слово ''&amp;quot;Миссисипи&amp;quot;''. Тогда алфавит будет &amp;lt;tex&amp;gt;A= \{&amp;lt;/tex&amp;gt; ''и, м, п, с'' &amp;lt;tex&amp;gt;\} &amp;lt;/tex&amp;gt;, а набор весов &amp;lt;tex&amp;gt;W=\{4, 1, 1, 3\}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 1 || 1 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
По алгоритму возьмем два символа с наименьшей частотой {{---}} это ''м'' и ''п''. Сформируем из них новый узел ''мп'' весом 2 и добавим его к списку узлов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мп || с &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 2 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Затем объединим в один узел узлы ''мп'' и ''c'':&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мпс &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 5 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
И, наконец, объединяем два узла ''и'' и ''мпс''. Итак, мы получили дерево Хаффмана и соответствующую ему таблицу кодов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Код || 0 || 100 || 101 || 11&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, закодированное слово ''&amp;quot;миссисипи&amp;quot;'' будет выглядеть как ''&amp;quot;1000111101101010&amp;quot;''. Длина закодированного слова {{---}} 16 бит. Стоит заметить, что если бы мы использовали для кодирования каждого символа из четырёх по 2 бита, длина закодированного слова составила бы 18 бит.&lt;br /&gt;
&lt;br /&gt;
== Корректность алгоритма Хаффмана ==&lt;br /&gt;
 &lt;br /&gt;
Чтобы доказать корректность алгоритма Хаффмана, покажем, что в задаче о построении оптимального префиксного кода проявляются свойства жадного выбора и оптимальной подструктуры. В сформулированной ниже лемме показано соблюдение свойства жадного выбора. &lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; — алфавит, каждый символ &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; которого встречается с частотой &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с самыми низкими частотами.&lt;br /&gt;
&lt;br /&gt;
Тогда для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; существует оптимальный префиксный код, кодовые слова символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; в котором имеют одинаковую максимальную длину и отличаются лишь последним битом. &lt;br /&gt;
|proof=&lt;br /&gt;
Возьмем дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, представляющее произвольный оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Преобразуем его в дерево, представляющее другой оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — листья с общим родительским узлом, находящиеся на максимальной глубине.&lt;br /&gt;
&lt;br /&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;T&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;f[a] \le f[b]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[x] \le f[y]&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y]&amp;lt;/tex&amp;gt; — две наименьшие частоты, а &amp;lt;tex&amp;gt;f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[b]&amp;lt;/tex&amp;gt; — две произвольные частоты, то выполняются отношения &amp;lt;tex&amp;gt;f[x] \le f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y] \le f[b]&amp;lt;/tex&amp;gt;. Пусть дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — дерево, полученное из &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; путем перестановки листьев &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, а дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево полученное из &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; перестановкой листьев &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Разность стоимостей деревьев &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; равна:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T) - B(T') = \sum\limits_{c \in C} f(c)d_T(c) - \sum\limits_{c \in C} f(c)d_{T'}(c) = (f[a] - f[x])(d_T(a) - d_T(x)),&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
что больше либо равно &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, так как величины &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; неотрицательны. Величина &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; неотрицательна, потому что &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — лист с минимальной частотой, а величина &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; является неотрицательной, так как лист &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; находится на максимальной глубине в дереве &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Точно так же перестановка листьев &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; не будет приводить к увеличению стоимости. Таким образом, разность &amp;lt;tex&amp;gt;B(T') - B(T'')&amp;lt;/tex&amp;gt; тоже будет неотрицательной.&lt;br /&gt;
&lt;br /&gt;
Таким образом, выполняется неравенство &amp;lt;tex&amp;gt;B(T'') \le B(T)&amp;lt;/tex&amp;gt;. С другой стороны, &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; — оптимальное дерево, поэтому должно выполняться неравенство &amp;lt;tex&amp;gt;B(T) \le B(T'')&amp;lt;/tex&amp;gt;. Отсюда следует, что &amp;lt;tex&amp;gt;B(T) = B(T'')&amp;lt;/tex&amp;gt;. Значит, &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево, представляющее оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; имеют одинаковую максимальную длину, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
 &lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=Пусть дан алфавит &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, в котором для каждого символа &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; определены частоты &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с минимальными частотами. Пусть &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; — алфавит, полученный из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; путем удаления символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и добавления нового символа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;, так что &amp;lt;tex&amp;gt;C' = C \backslash \{ x, y \} \cup {z}&amp;lt;/tex&amp;gt;. По определению частоты &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; в алфавите &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; совпадают с частотами в алфавите &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, за исключением частоты &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — произвольное дерево, представляющее оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; Тогда дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, полученное из дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; путем замены листа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; внутренним узлом с дочерними элементами &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof=&lt;br /&gt;
Сначала покажем, что стоимость &amp;lt;tex&amp;gt;B(T)&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; может быть выражена через стоимость &amp;lt;tex&amp;gt;B(T')&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt;. Для каждого символа &amp;lt;tex&amp;gt;c \in C \backslash \{x, y \}&amp;lt;/tex&amp;gt; верно &amp;lt;tex&amp;gt;d_T(C) = d_{T'}&amp;lt;/tex&amp;gt;, значит, &amp;lt;tex&amp;gt;f[c]d_T(c) = f[c]d_{T'}(c)&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;d_T(x) = d_T(y) = d_{T'} (z) + 1&amp;lt;/tex&amp;gt;, то&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f[x]d_T(x) + f[y]d_T(y) = (f[x] + f[y])(d_{T'}(z) + 1) = f[z]d_{T'}(z) + (f[x] + f[y])&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
из чего следует, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T) = B(T') + f[x] + f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T') = B(T) - f[x] - f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем лемму от противного. Предположим, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Тогда существует дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;B(T'') &amp;lt; B(T)&amp;lt;/tex&amp;gt;. Согласно лемме (1), элементы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; можно считать дочерними элементами одного узла. Пусть дерево &amp;lt;tex&amp;gt;T'''&amp;lt;/tex&amp;gt; получено из дерева &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; заменой элементов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; листом &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; с частотой &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Тогда&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T''') = B(T'') - f[x] - f[y] &amp;lt; B(T) - f[x] - f[y] = B(T')&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
что противоречит предположению о том, что дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt;. Значит, наше предположение о том, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, неверно, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Алгоритм Хаффмана дает [[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | оптимальный префиксный код]]. &lt;br /&gt;
|proof=&lt;br /&gt;
Справедливость теоремы непосредственно следует из лемм (1) и (2)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — с. 459. — ISBN 5-8489-0857-4&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Алгоритм_Хаффмана Википедия — Алгоритм Хаффмана]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Wikipedia — Huffman coding]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%C4%E2%EE%E8%F7%ED%EE%E5_%E4%E5%F0%E5%E2%EE Википедия — Бинарное дерево]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Префиксный_код Википедия — Префиксный код]&lt;br /&gt;
*[[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | Задача об оптимальном префиксном коде]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33990</id>
		<title>Алгоритм Хаффмана</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33990"/>
				<updated>2013-12-09T15:45:55Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''''Алгоритм Хаффмана''''' — алгоритм оптимального префиксного кодирования алфавита. Был разработан в 1952 году аспирантом Массачусетского технологического института Дэвидом Хаффманом при написании им курсовой работы. Используется во многих программах сжатия данных, например, PKZIP 2, LZH и др.&lt;br /&gt;
&lt;br /&gt;
== Определение ==&lt;br /&gt;
&lt;br /&gt;
{{Определение &lt;br /&gt;
|definition=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;W=\{w_{1},w_{2},...,w_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Тогда набор бинарных кодов &amp;lt;tex&amp;gt;C=\{c_{1},c_{2},...,c_{n}\}&amp;lt;/tex&amp;gt;, такой, что:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;gt; не является префиксом для &amp;lt;tex&amp;gt;c_{j}&amp;lt;/tex&amp;gt;, при &amp;lt;tex&amp;gt;i \ne j&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Сумма &amp;lt;tex&amp;gt;\sum\limits_{i \in [1, n]} w_{i}\cdot c_{i}&amp;lt;/tex&amp;gt; минимальна. (&amp;lt;tex&amp;gt;|c_{i}|&amp;lt;/tex&amp;gt; — длина кода &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;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;
1. Составим [[Список | список]] кодируемых символов, при этом будем рассматривать один символ как дерево, состоящее из одного элемента, весом, равным частоте появления символа в тексте.&lt;br /&gt;
&lt;br /&gt;
2. Из списка выберем два узла с наименьшим весом.&lt;br /&gt;
&lt;br /&gt;
3. Сформируем новый узел с весом, равным сумме весов выбранных узлов, и присоединим к нему два выбранных узла в качестве дочерних.&lt;br /&gt;
&lt;br /&gt;
4. Добавим к списку только что сформированный узел.&lt;br /&gt;
&lt;br /&gt;
5. Если в списке больше одного узла, то повторить пункты со второго по пятый.&lt;br /&gt;
&lt;br /&gt;
== Время работы ==&lt;br /&gt;
Если сортировать элементы после каждого суммирования или использовать очередь с приоритетами, то такой алгоритм будет работать за время &amp;lt;tex&amp;gt;O(NlogN)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Mississippi.png|400px|thumb|right|Дерево Хаффмана для слова ''&amp;quot;Миссисипи&amp;quot;'']]&lt;br /&gt;
&lt;br /&gt;
Для примера возьмём слово ''&amp;quot;Миссисипи&amp;quot;''. Тогда алфавит будет &amp;lt;tex&amp;gt;A= \{&amp;lt;/tex&amp;gt; ''и, м, п, с'' &amp;lt;tex&amp;gt;\} &amp;lt;/tex&amp;gt;, а набор весов &amp;lt;tex&amp;gt;W=\{4, 1, 1, 3\}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 1 || 1 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
По алгоритму возьмем два символа с наименьшей частотой {{---}} это ''м'' и ''п''. Сформируем из них новый узел ''мп'' весом 2 и добавим его к списку узлов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мп || с &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 2 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Затем объединим в один узел узлы ''мп'' и ''c'':&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мпс &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 5 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
И, наконец, объединяем два узла ''и'' и ''мпс''. Итак, мы получили дерево Хаффмана и соответствующую ему таблицу кодов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Код || 0 || 100 || 101 || 11&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, закодированное слово ''&amp;quot;миссисипи&amp;quot;'' будет выглядеть как ''&amp;quot;1000111101101010&amp;quot;''. Длина закодированного слова {{---}} 16 бит. Стоит заметить, что если бы мы использовали для кодирования каждого символа из четырёх по 2 бита, длина закодированного слова составила бы 18 бит.&lt;br /&gt;
&lt;br /&gt;
== Корректность алгоритма Хаффмана ==&lt;br /&gt;
 &lt;br /&gt;
Чтобы доказать корректность алгоритма Хаффмана, покажем, что в задаче о построении оптимального префиксного кода проявляются свойства жадного выбора и оптимальной подструктуры. В сформулированной ниже лемме показано соблюдение свойства жадного выбора. &lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; — алфавит, каждый символ &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; которого встречается с частотой &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с самыми низкими частотами.&lt;br /&gt;
&lt;br /&gt;
Тогда для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; существует оптимальный префиксный код, кодовые слова символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; в котором имеют одинаковую максимальную длину и отличаются лишь последним битом. &lt;br /&gt;
|proof=&lt;br /&gt;
Возьмем дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, представляющее произвольный оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Преобразуем его в дерево, представляющее другой оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — листья с общим родительским узлом, находящиеся на максимальной глубине.&lt;br /&gt;
&lt;br /&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;T&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;f[a] \le f[b]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[x] \le f[y]&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y]&amp;lt;/tex&amp;gt; — две наименьшие частоты, а &amp;lt;tex&amp;gt;f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[b]&amp;lt;/tex&amp;gt; — две произвольные частоты, то выполняются отношения &amp;lt;tex&amp;gt;f[x] \le f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y] \le f[b]&amp;lt;/tex&amp;gt;. Пусть дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — дерево, полученное из &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; путем перестановки листьев &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, а дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево полученное из &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; перестановкой листьев &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Разность стоимостей деревьев &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; равна:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T) - B(T') = \sum\limits_{c \in C} f(c)d_T(c) - \sum\limits_{c \in C} f(c)d_{T'}(c) = (f[a] - f[x])(d_T(a) - d_T(x)),&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
что больше либо равно &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, так как величины &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; неотрицательны. Величина &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; неотрицательна, потому что &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — лист с минимальной частотой, а величина &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; является неотрицательной, так как лист &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; находится на максимальной глубине в дереве &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Точно так же перестановка листьев &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; не будет приводить к увеличению стоимости. Таким образом, разность &amp;lt;tex&amp;gt;B(T') - B(T'')&amp;lt;/tex&amp;gt; тоже будет неотрицательной.&lt;br /&gt;
&lt;br /&gt;
Таким образом, выполняется неравенство &amp;lt;tex&amp;gt;B(T'') \le B(T)&amp;lt;/tex&amp;gt;. С другой стороны, &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; — оптимальное дерево, поэтому должно выполняться неравенство &amp;lt;tex&amp;gt;B(T) \le B(T'')&amp;lt;/tex&amp;gt;. Отсюда следует, что &amp;lt;tex&amp;gt;B(T) = B(T'')&amp;lt;/tex&amp;gt;. Значит, &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево, представляющее оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; имеют одинаковую максимальную длину, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
 &lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=Пусть дан алфавит &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, в котором для каждого символа &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; определены частоты &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с минимальными частотами. Пусть &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; — алфавит, полученный из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; путем удаления символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и добавления нового символа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;, так что &amp;lt;tex&amp;gt;C' = C \backslash \{ x, y \} \cup {z}&amp;lt;/tex&amp;gt;. По определению частоты &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; в алфавите &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; совпадают с частотами в алфавите &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, за исключением частоты &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — произвольное дерево, представляющее оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; Тогда дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, полученное из дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; путем замены листа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; внутренним узлом с дочерними элементами &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof=&lt;br /&gt;
Сначала покажем, что стоимость &amp;lt;tex&amp;gt;B(T)&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; может быть выражена через стоимость &amp;lt;tex&amp;gt;B(T')&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt;. Для каждого символа &amp;lt;tex&amp;gt;c \in C \backslash \{x, y \}&amp;lt;/tex&amp;gt; верно &amp;lt;tex&amp;gt;d_T(C) = d_{T'}&amp;lt;/tex&amp;gt;, значит, &amp;lt;tex&amp;gt;f[c]d_T(c) = f[c]d_{T'}(c)&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;d_T(x) = d_T(y) = d_{T'} (z) + 1&amp;lt;/tex&amp;gt;, то&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f[x]d_T(x) + f[y]d_T(y) = (f[x] + f[y])(d_{T'}(z) + 1) = f[z]d_{T'}(z) + (f[x] + f[y])&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
из чего следует, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T) = B(T') + f[x] + f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T') = B(T) - f[x] - f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем лемму от противного. Предположим, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Тогда существует дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;B(T'') &amp;lt; B(T)&amp;lt;/tex&amp;gt;. Согласно лемме (1), элементы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; можно считать дочерними элементами одного узла. Пусть дерево &amp;lt;tex&amp;gt;T'''&amp;lt;/tex&amp;gt; получено из дерева &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; заменой элементов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; листом &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; с частотой &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Тогда&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T''') = B(T'') - f[x] - f[y] &amp;lt; B(T) - f[x] - f[y] = B(T')&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
что противоречит предположению о том, что дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt;. Значит, наше предположение о том, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, неверно, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Алгоритм Хаффмана дает [[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | оптимальный префиксный код]]. &lt;br /&gt;
|proof=&lt;br /&gt;
Справедливость теоремы непосредственно следует из лемм (1) и (2)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — с. 459. — ISBN 5-8489-0857-4&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Алгоритм_Хаффмана Википедия — Алгоритм Хаффмана]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Wikipedia — Huffman coding]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%C4%E2%EE%E8%F7%ED%EE%E5_%E4%E5%F0%E5%E2%EE Википедия — Бинарное дерево]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Префиксный_код Википедия — Префиксный код]&lt;br /&gt;
*[[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | Задача об оптимальном префиксном коде]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33989</id>
		<title>Алгоритм Хаффмана</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33989"/>
				<updated>2013-12-09T15:32:55Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: /* Алгоритм */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''''Алгоритм Хаффмана''''' — алгоритм оптимального префиксного кодирования алфавита. Был разработан в 1952 году аспирантом Массачусетского технологического института Дэвидом Хаффманом при написании им курсовой работы. Используется во многих программах сжатия данных, например, PKZIP 2, LZH и др.&lt;br /&gt;
&lt;br /&gt;
== Определение ==&lt;br /&gt;
&lt;br /&gt;
{{Определение &lt;br /&gt;
|definition=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;W=\{w_{1},w_{2},...,w_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Тогда набор бинарных кодов &amp;lt;tex&amp;gt;C=\{c_{1},c_{2},...,c_{n}\}&amp;lt;/tex&amp;gt;, такой, что:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;gt; не является префиксом для &amp;lt;tex&amp;gt;c_{j}&amp;lt;/tex&amp;gt;, при &amp;lt;tex&amp;gt;i \ne j&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Сумма &amp;lt;tex&amp;gt;\sum\limits_{i \in [1, n]} w_{i}\cdot c_{i}&amp;lt;/tex&amp;gt; минимальна. (&amp;lt;tex&amp;gt;|c_{i}|&amp;lt;/tex&amp;gt; — длина кода &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;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;
1. Составим [[Список | список]] кодируемых символов, при этом будем рассматривать один символ как дерево, состоящее из одного элемента, весом, равным частоте появления символа в тексте.&lt;br /&gt;
&lt;br /&gt;
2. Из списка выберем два узла с наименьшим весом.&lt;br /&gt;
&lt;br /&gt;
3. Сформируем новый узел с весом, равным сумме весов выбранных узлов, и присоединим к нему два выбранных узла в качестве дочерних.&lt;br /&gt;
&lt;br /&gt;
4. Добавим к списку только что сформированный узел.&lt;br /&gt;
&lt;br /&gt;
5. Если в списке больше одного узла, то повторить пункты со второго по пятый.&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Mississippi.png|400px|thumb|right|Дерево Хаффмана для слова ''&amp;quot;Миссисипи&amp;quot;'']]&lt;br /&gt;
&lt;br /&gt;
Для примера возьмём слово ''&amp;quot;Миссисипи&amp;quot;''. Тогда алфавит будет &amp;lt;tex&amp;gt;A= \{&amp;lt;/tex&amp;gt; ''и, м, п, с'' &amp;lt;tex&amp;gt;\} &amp;lt;/tex&amp;gt;, а набор весов &amp;lt;tex&amp;gt;W=\{4, 1, 1, 3\}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 1 || 1 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
По алгоритму возьмем два символа с наименьшей частотой {{---}} это ''м'' и ''п''. Сформируем из них новый узел ''мп'' весом 2 и добавим его к списку узлов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мп || с &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 2 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Затем объединим в один узел узлы ''мп'' и ''c'':&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мпс &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 5 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
И, наконец, объединяем два узла ''и'' и ''мпс''. Итак, мы получили дерево Хаффмана и соответствующую ему таблицу кодов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Код || 0 || 100 || 101 || 11&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, закодированное слово ''&amp;quot;миссисипи&amp;quot;'' будет выглядеть как ''&amp;quot;1000111101101010&amp;quot;''. Длина закодированного слова {{---}} 16 бит. Стоит заметить, что если бы мы использовали для кодирования каждого символа из четырёх по 2 бита, длина закодированного слова составила бы 18 бит.&lt;br /&gt;
&lt;br /&gt;
== Корректность алгоритма Хаффмана ==&lt;br /&gt;
 &lt;br /&gt;
Чтобы доказать корректность алгоритма Хаффмана, покажем, что в задаче о построении оптимального префиксного кода проявляются свойства жадного выбора и оптимальной подструктуры. В сформулированной ниже лемме показано соблюдение свойства жадного выбора. &lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; — алфавит, каждый символ &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; которого встречается с частотой &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с самыми низкими частотами.&lt;br /&gt;
&lt;br /&gt;
Тогда для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; существует оптимальный префиксный код, кодовые слова символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; в котором имеют одинаковую максимальную длину и отличаются лишь последним битом. &lt;br /&gt;
|proof=&lt;br /&gt;
Возьмем дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, представляющее произвольный оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Преобразуем его в дерево, представляющее другой оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — листья с общим родительским узлом, находящиеся на максимальной глубине.&lt;br /&gt;
&lt;br /&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;T&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;f[a] \le f[b]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[x] \le f[y]&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y]&amp;lt;/tex&amp;gt; — две наименьшие частоты, а &amp;lt;tex&amp;gt;f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[b]&amp;lt;/tex&amp;gt; — две произвольные частоты, то выполняются отношения &amp;lt;tex&amp;gt;f[x] \le f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y] \le f[b]&amp;lt;/tex&amp;gt;. Пусть дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — дерево, полученное из &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; путем перестановки листьев &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, а дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево полученное из &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; перестановкой листьев &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Разность стоимостей деревьев &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; равна:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T) - B(T') = \sum\limits_{c \in C} f(c)d_T(c) - \sum\limits_{c \in C} f(c)d_{T'}(c) = (f[a] - f[x])(d_T(a) - d_T(x)),&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
что больше либо равно &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, так как величины &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; неотрицательны. Величина &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; неотрицательна, потому что &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — лист с минимальной частотой, а величина &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; является неотрицательной, так как лист &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; находится на максимальной глубине в дереве &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Точно так же перестановка листьев &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; не будет приводить к увеличению стоимости. Таким образом, разность &amp;lt;tex&amp;gt;B(T') - B(T'')&amp;lt;/tex&amp;gt; тоже будет неотрицательной.&lt;br /&gt;
&lt;br /&gt;
Таким образом, выполняется неравенство &amp;lt;tex&amp;gt;B(T'') \le B(T)&amp;lt;/tex&amp;gt;. С другой стороны, &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; — оптимальное дерево, поэтому должно выполняться неравенство &amp;lt;tex&amp;gt;B(T) \le B(T'')&amp;lt;/tex&amp;gt;. Отсюда следует, что &amp;lt;tex&amp;gt;B(T) = B(T'')&amp;lt;/tex&amp;gt;. Значит, &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево, представляющее оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; имеют одинаковую максимальную длину, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
 &lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=Пусть дан алфавит &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, в котором для каждого символа &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; определены частоты &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с минимальными частотами. Пусть &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; — алфавит, полученный из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; путем удаления символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и добавления нового символа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;, так что &amp;lt;tex&amp;gt;C' = C \backslash \{ x, y \} \cup {z}&amp;lt;/tex&amp;gt;. По определению частоты &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; в алфавите &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; совпадают с частотами в алфавите &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, за исключением частоты &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — произвольное дерево, представляющее оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; Тогда дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, полученное из дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; путем замены листа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; внутренним узлом с дочерними элементами &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof=&lt;br /&gt;
Сначала покажем, что стоимость &amp;lt;tex&amp;gt;B(T)&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; может быть выражена через стоимость &amp;lt;tex&amp;gt;B(T')&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt;. Для каждого символа &amp;lt;tex&amp;gt;c \in C \backslash \{x, y \}&amp;lt;/tex&amp;gt; верно &amp;lt;tex&amp;gt;d_T(C) = d_{T'}&amp;lt;/tex&amp;gt;, значит, &amp;lt;tex&amp;gt;f[c]d_T(c) = f[c]d_{T'}(c)&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;d_T(x) = d_T(y) = d_{T'} (z) + 1&amp;lt;/tex&amp;gt;, то&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f[x]d_T(x) + f[y]d_T(y) = (f[x] + f[y])(d_{T'}(z) + 1) = f[z]d_{T'}(z) + (f[x] + f[y])&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
из чего следует, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T) = B(T') + f[x] + f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T') = B(T) - f[x] - f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем лемму от противного. Предположим, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Тогда существует дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;B(T'') &amp;lt; B(T)&amp;lt;/tex&amp;gt;. Согласно лемме (1), элементы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; можно считать дочерними элементами одного узла. Пусть дерево &amp;lt;tex&amp;gt;T'''&amp;lt;/tex&amp;gt; получено из дерева &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; заменой элементов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; листом &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; с частотой &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Тогда&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T''') = B(T'') - f[x] - f[y] &amp;lt; B(T) - f[x] - f[y] = B(T')&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
что противоречит предположению о том, что дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt;. Значит, наше предположение о том, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, неверно, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Алгоритм Хаффмана дает [[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | оптимальный префиксный код]]. &lt;br /&gt;
|proof=&lt;br /&gt;
Справедливость теоремы непосредственно следует из лемм (1) и (2)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — с. 459. — ISBN 5-8489-0857-4&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Алгоритм_Хаффмана Википедия — Алгоритм Хаффмана]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Wikipedia — Huffman coding]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%C4%E2%EE%E8%F7%ED%EE%E5_%E4%E5%F0%E5%E2%EE Википедия — Бинарное дерево]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Префиксный_код Википедия — Префиксный код]&lt;br /&gt;
*[[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | Задача об оптимальном префиксном коде]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33988</id>
		<title>Алгоритм Хаффмана</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33988"/>
				<updated>2013-12-09T15:29:25Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''''Алгоритм Хаффмана''''' — алгоритм оптимального префиксного кодирования алфавита. Был разработан в 1952 году аспирантом Массачусетского технологического института Дэвидом Хаффманом при написании им курсовой работы. Используется во многих программах сжатия данных, например, PKZIP 2, LZH и др.&lt;br /&gt;
&lt;br /&gt;
== Определение ==&lt;br /&gt;
&lt;br /&gt;
{{Определение &lt;br /&gt;
|definition=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;W=\{w_{1},w_{2},...,w_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Тогда набор бинарных кодов &amp;lt;tex&amp;gt;C=\{c_{1},c_{2},...,c_{n}\}&amp;lt;/tex&amp;gt;, такой, что:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;gt; не является префиксом для &amp;lt;tex&amp;gt;c_{j}&amp;lt;/tex&amp;gt;, при &amp;lt;tex&amp;gt;i \ne j&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Сумма &amp;lt;tex&amp;gt;\sum\limits_{i \in [1, n]} w_{i}\cdot c_{i}&amp;lt;/tex&amp;gt; минимальна. (&amp;lt;tex&amp;gt;|c_{i}|&amp;lt;/tex&amp;gt; — длина кода &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;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;
1. Составим список кодируемых символов, при этом будем рассматривать один символ как дерево, состоящее из одного элемента, весом, равным частоте появления символа в тексте.&lt;br /&gt;
&lt;br /&gt;
2. Из списка выберем два узла с наименьшим весом.&lt;br /&gt;
&lt;br /&gt;
3. Сформируем новый узел с весом, равным сумме весов выбранных узлов, и присоединим к нему два выбранных узла в качестве дочерних.&lt;br /&gt;
&lt;br /&gt;
4. Добавим к списку только что сформированный узел.&lt;br /&gt;
&lt;br /&gt;
5. Если в списке больше одного узла, то повторить пункты со второго по пятый.&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Mississippi.png|400px|thumb|right|Дерево Хаффмана для слова ''&amp;quot;Миссисипи&amp;quot;'']]&lt;br /&gt;
&lt;br /&gt;
Для примера возьмём слово ''&amp;quot;Миссисипи&amp;quot;''. Тогда алфавит будет &amp;lt;tex&amp;gt;A= \{&amp;lt;/tex&amp;gt; ''и, м, п, с'' &amp;lt;tex&amp;gt;\} &amp;lt;/tex&amp;gt;, а набор весов &amp;lt;tex&amp;gt;W=\{4, 1, 1, 3\}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 1 || 1 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
По алгоритму возьмем два символа с наименьшей частотой {{---}} это ''м'' и ''п''. Сформируем из них новый узел ''мп'' весом 2 и добавим его к списку узлов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мп || с &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 2 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Затем объединим в один узел узлы ''мп'' и ''c'':&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мпс &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 5 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
И, наконец, объединяем два узла ''и'' и ''мпс''. Итак, мы получили дерево Хаффмана и соответствующую ему таблицу кодов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Код || 0 || 100 || 101 || 11&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, закодированное слово ''&amp;quot;миссисипи&amp;quot;'' будет выглядеть как ''&amp;quot;1000111101101010&amp;quot;''. Длина закодированного слова {{---}} 16 бит. Стоит заметить, что если бы мы использовали для кодирования каждого символа из четырёх по 2 бита, длина закодированного слова составила бы 18 бит.&lt;br /&gt;
&lt;br /&gt;
== Корректность алгоритма Хаффмана ==&lt;br /&gt;
 &lt;br /&gt;
Чтобы доказать корректность алгоритма Хаффмана, покажем, что в задаче о построении оптимального префиксного кода проявляются свойства жадного выбора и оптимальной подструктуры. В сформулированной ниже лемме показано соблюдение свойства жадного выбора. &lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; — алфавит, каждый символ &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; которого встречается с частотой &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с самыми низкими частотами.&lt;br /&gt;
&lt;br /&gt;
Тогда для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; существует оптимальный префиксный код, кодовые слова символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; в котором имеют одинаковую максимальную длину и отличаются лишь последним битом. &lt;br /&gt;
|proof=&lt;br /&gt;
Возьмем дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, представляющее произвольный оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Преобразуем его в дерево, представляющее другой оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — листья с общим родительским узлом, находящиеся на максимальной глубине.&lt;br /&gt;
&lt;br /&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;T&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;f[a] \le f[b]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[x] \le f[y]&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y]&amp;lt;/tex&amp;gt; — две наименьшие частоты, а &amp;lt;tex&amp;gt;f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[b]&amp;lt;/tex&amp;gt; — две произвольные частоты, то выполняются отношения &amp;lt;tex&amp;gt;f[x] \le f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y] \le f[b]&amp;lt;/tex&amp;gt;. Пусть дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — дерево, полученное из &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; путем перестановки листьев &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, а дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево полученное из &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; перестановкой листьев &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Разность стоимостей деревьев &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; равна:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T) - B(T') = \sum\limits_{c \in C} f(c)d_T(c) - \sum\limits_{c \in C} f(c)d_{T'}(c) = (f[a] - f[x])(d_T(a) - d_T(x)),&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
что больше либо равно &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, так как величины &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; неотрицательны. Величина &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; неотрицательна, потому что &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — лист с минимальной частотой, а величина &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; является неотрицательной, так как лист &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; находится на максимальной глубине в дереве &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Точно так же перестановка листьев &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; не будет приводить к увеличению стоимости. Таким образом, разность &amp;lt;tex&amp;gt;B(T') - B(T'')&amp;lt;/tex&amp;gt; тоже будет неотрицательной.&lt;br /&gt;
&lt;br /&gt;
Таким образом, выполняется неравенство &amp;lt;tex&amp;gt;B(T'') \le B(T)&amp;lt;/tex&amp;gt;. С другой стороны, &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; — оптимальное дерево, поэтому должно выполняться неравенство &amp;lt;tex&amp;gt;B(T) \le B(T'')&amp;lt;/tex&amp;gt;. Отсюда следует, что &amp;lt;tex&amp;gt;B(T) = B(T'')&amp;lt;/tex&amp;gt;. Значит, &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево, представляющее оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; имеют одинаковую максимальную длину, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
 &lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=Пусть дан алфавит &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, в котором для каждого символа &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; определены частоты &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с минимальными частотами. Пусть &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; — алфавит, полученный из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; путем удаления символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и добавления нового символа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;, так что &amp;lt;tex&amp;gt;C' = C \backslash \{ x, y \} \cup {z}&amp;lt;/tex&amp;gt;. По определению частоты &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; в алфавите &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; совпадают с частотами в алфавите &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, за исключением частоты &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — произвольное дерево, представляющее оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; Тогда дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, полученное из дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; путем замены листа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; внутренним узлом с дочерними элементами &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof=&lt;br /&gt;
Сначала покажем, что стоимость &amp;lt;tex&amp;gt;B(T)&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; может быть выражена через стоимость &amp;lt;tex&amp;gt;B(T')&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt;. Для каждого символа &amp;lt;tex&amp;gt;c \in C \backslash \{x, y \}&amp;lt;/tex&amp;gt; верно &amp;lt;tex&amp;gt;d_T(C) = d_{T'}&amp;lt;/tex&amp;gt;, значит, &amp;lt;tex&amp;gt;f[c]d_T(c) = f[c]d_{T'}(c)&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;d_T(x) = d_T(y) = d_{T'} (z) + 1&amp;lt;/tex&amp;gt;, то&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f[x]d_T(x) + f[y]d_T(y) = (f[x] + f[y])(d_{T'}(z) + 1) = f[z]d_{T'}(z) + (f[x] + f[y])&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
из чего следует, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T) = B(T') + f[x] + f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T') = B(T) - f[x] - f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем лемму от противного. Предположим, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Тогда существует дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;B(T'') &amp;lt; B(T)&amp;lt;/tex&amp;gt;. Согласно лемме (1), элементы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; можно считать дочерними элементами одного узла. Пусть дерево &amp;lt;tex&amp;gt;T'''&amp;lt;/tex&amp;gt; получено из дерева &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; заменой элементов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; листом &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; с частотой &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Тогда&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T''') = B(T'') - f[x] - f[y] &amp;lt; B(T) - f[x] - f[y] = B(T')&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
что противоречит предположению о том, что дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt;. Значит, наше предположение о том, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, неверно, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Алгоритм Хаффмана дает [[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | оптимальный префиксный код]]. &lt;br /&gt;
|proof=&lt;br /&gt;
Справедливость теоремы непосредственно следует из лемм (1) и (2)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — с. 459. — ISBN 5-8489-0857-4&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Алгоритм_Хаффмана Википедия — Алгоритм Хаффмана]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Wikipedia — Huffman coding]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%C4%E2%EE%E8%F7%ED%EE%E5_%E4%E5%F0%E5%E2%EE Википедия — Бинарное дерево]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Префиксный_код Википедия — Префиксный код]&lt;br /&gt;
*[[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | Задача об оптимальном префиксном коде]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:KKutirev&amp;diff=33958</id>
		<title>Обсуждение участника:KKutirev</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:KKutirev&amp;diff=33958"/>
				<updated>2013-12-07T19:46:56Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: /* Алгоритм Хаффмана за   O(n) . */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Алгоритм Хаффмана за  &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt;. ==&lt;br /&gt;
&lt;br /&gt;
У нас есть массив частот, отсортированный по возрастанию, нужно построить по нему код Хаффмана за &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt; (но если массив не отсортирован, то это можно сделать цифровой сортировкой за  &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt; что не ухудшит решение).&lt;br /&gt;
&lt;br /&gt;
Идея алгоритма заключается в том, чтобы создать такую очередь с приоритетами, из которой можно было бы доставать два минимума &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;, после чего в эту же очередь с приоритетами положить их сумму за &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;. У нас уже есть массив с отсортированными частотами, теперь давайте заведем второй массив, в котором мы будем хранить суммы. Несложно заметить, что в этом массиве элементы тоже будут идти по неубыванию. Допустим, что на каком-то шаге сумма получилась меньше чем предыдущая, но это противоречит тому, что на каждом шаге мы выбираем два минимальных (т.е. на каждом последующем шаге мы выбираем два минимума из элементов больших, чем на предыдущем шаге). &lt;br /&gt;
Тогда на каждой итерации мы будет выбирать два минимума из четырех элементов (первые 2 элемента первого массива и первые 2 элемента второго массива). Теперь рассмотрим одну итерацию подробнее. &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;
В алгоритме &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; итерации, так как на каждой итерации количество элементов  уменьшается ровно на один, а минимум из 4-х элементов мы выбираем за константное время.&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:KKutirev&amp;diff=33957</id>
		<title>Обсуждение участника:KKutirev</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:KKutirev&amp;diff=33957"/>
				<updated>2013-12-07T19:39:05Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: /* Алгоритм Хаффмана за   O(n) . */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Алгоритм Хаффмана за  &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt;. ==&lt;br /&gt;
&lt;br /&gt;
У нас есть массив частот, отсортированный по возрастанию, нужно построить по нему код Хаффмана за &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt; (но если массив не отсортирован, то это можно сделать цифровой сортировкой за  &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt; что не ухудшит решение).&lt;br /&gt;
&lt;br /&gt;
Идея алгоритма заключается в том, чтобы создать такую очередь с приоритетами, из которой можно было бы доставать два минимума &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;, после чего в эту же очередь с приоритетами положить их сумму за &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;. У нас уже есть массив с отсортированными частотами, теперь давайте заведем второй массив, в котором мы будем хранить суммы. Несложно заметить, что в этом массиве элементы тоже будут идти по неубыванию. Допустим, что на каком-то шаге сумма получилась меньше чем предыдущая, но это противоречит тому, что на каждом шаге мы выбираем два минимальных (т.е. на каждом последующем шаге мы выбираем два минимума из элементов больших, чем на предыдущем шаге).  Тогда на каждой итерации мы будет выбирать два минимума из четырех элементов (первые 2 элемента первого массива и первые 2 элемента второго массива). Теперь рассмотрим одну итерацию подробнее. &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;
В алгоритме &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; итерации, так как на каждой итерации количество элементов  уменьшается ровно на один, а минимум из 4-х элементов мы выбираем за константное время.&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:KKutirev&amp;diff=33956</id>
		<title>Обсуждение участника:KKutirev</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:KKutirev&amp;diff=33956"/>
				<updated>2013-12-07T19:32:48Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: /* Алгоритм Хаффмана за   O(n) . */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Алгоритм Хаффмана за  &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt;. ==&lt;br /&gt;
&lt;br /&gt;
У нас есть массив частот, отсортированный по возрастанию, нужно построить по нему код Хаффмана за &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt; (но если массив не отсортирован, то это можно сделать цифровой сортировкой за  &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt; что не ухудшит решение).&lt;br /&gt;
&lt;br /&gt;
Идея алгоритма заключается в том, чтобы создать такую очередь с приоритетами, из которой можно было бы доставать два минимума &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;, после чего в эту же очередь с приоритетами положить их сумму за &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;. У нас уже есть массив с отсортированными частотами, теперь давайте заведем второй массив, в котором мы будем хранить суммы. Несложно заметить, что в этом массиве элементы тоже будут идти по неубыванию. Допустим, что на каком-то шаге сумма получилась меньше чем предыдущая, но это противоречит тому, что на каждом шаге мы выбираем два минимальных (т.е. на каждом последующем шаге мы выбираем два минимума из элементов больших, чем на предыдущем шаге).  Тогда на каждой итерации мы будет выбирать два минимума из четырех элементов (первые 2 элемента первого массива и первые 2 элемента второго массива). Теперь рассмотрим одну итерацию подробнее. У нас есть три варианта возможных пар минимумов. Первый: оба элемента из первого массива. Второй: первый элемент первого массива и первый элемент второго массива. И третий: два первых элемента второго массива. В первом варианте мы просто дописываем сумму в конец второго массива. Во втором варианте мы вычеркиваем первый элемент из второго массива и добавляем его сумму с первым элементом первого массива в конец второго. Ну и в третьем варианте, мы вычеркиваем два первых элемента второго массива и добавляем их сумму в конец этого массива. Если в первом массиве элементы закончились, а во втором осталось больше одного элемента, то они меняются ролями.&lt;br /&gt;
&lt;br /&gt;
В алгоритме &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; итерации, так как на каждой итерации количество элементов  уменьшается ровно на один, а минимум из 4-х элементов мы выбираем за константное время.&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:KKutirev&amp;diff=33955</id>
		<title>Обсуждение участника:KKutirev</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:KKutirev&amp;diff=33955"/>
				<updated>2013-12-07T19:29:41Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: /* Алгоритм Хаффмана за   O(n) . */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Алгоритм Хаффмана за  &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt;. ==&lt;br /&gt;
&lt;br /&gt;
У нас есть массив частот, отсортированный по возрастанию, нужно построить по нему код Хаффмана за &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt; (но если массив не отсортирован, то это можно сделать цифровой сортировкой за  &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt; что не ухудшит решение).&lt;br /&gt;
&lt;br /&gt;
Идея алгоритма заключается в том, чтобы создать такую очередь с приоритетами, из которой можно было бы доставать два минимума &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;, после чего в эту же очередь с приоритетами положить их сумму за &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;. У нас уже есть массив с отсортированными частотами, теперь давайте заведем второй массив, в котором мы будем хранить суммы. Несложно заметить, что в этом массиве элементы тоже будут идти по неубыванию. Допустим, что на каком-то шаге сумма получилась меньше чем предыдущая, но это противоречит тому, что на каждом шаге мы выбираем два минимальных (т.е. на каждом последующем шаге мы выбираем два минимума из элементов больших, чем на предыдущем шаге).  Тогда на каждой итерации мы будет выбирать два минимума из четырех элементов (первые 2 элемента первого массива и первые 2 элемента второго массива). Теперь рассмотрим одну итерацию подробнее. У нас есть три варианта возможных пар минимумов. Первый: оба элемента из первого массива. Второй: первый элемент первого массива и первый элемент второго массива. И третий: два первых элемента второго массива. В первом варианте мы просто дописываем сумму в конец второго массива. Во втором варианте мы вычеркиваем первый элемент из второго массива и добавляем его сумму с первым элементом первого массива в конец второго. Ну и в третьем варианте, мы вычеркиваем два первых элемента второго массива и добавляем их сумму в конец этого массива. Если в первом массиве элементы закончились, а во втором осталось больше одного элемента, то они меняются ролями.&lt;br /&gt;
&lt;br /&gt;
В алгоритме происходит ровно &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; итерации, так как на каждой итерации количество элементов  уменьшается ровно на один, а минимум из 4-х элементов мы выбираем за константное время.&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:KKutirev&amp;diff=33954</id>
		<title>Обсуждение участника:KKutirev</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:KKutirev&amp;diff=33954"/>
				<updated>2013-12-07T19:27:23Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: /* Алгоритм Хаффмана за O(n). */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Алгоритм Хаффмана за  &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt;. ==&lt;br /&gt;
&lt;br /&gt;
У нас есть массив частот, отсортированный по возрастанию, нужно построить по нему код Хаффмана за &amp;lt;tex&amp;gt; O(n) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Идея алгоритма заключается в том, чтобы создать такую очередь с приоритетами, из которой можно было бы доставать два минимума &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;, после чего в эту же очередь с приоритетами положить их сумму за &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;. У нас уже есть массив с отсортированными частотами, теперь давайте заведем второй массив, в котором мы будем хранить суммы. Несложно заметить, что в этом массиве элементы тоже будут идти по неубыванию. Допустим, что на каком-то шаге сумма получилась меньше чем предыдущая, но это противоречит тому, что на каждом шаге мы выбираем два минимальных (т.е. на каждом последующем шаге мы выбираем два минимума из элементов больших, чем на предыдущем шаге).  Тогда на каждой итерации мы будет выбирать два минимума из четырех элементов (первые 2 элемента первого массива и первые 2 элемента второго массива). Теперь рассмотрим одну итерацию подробнее. У нас есть три варианта возможных пар минимумов. Первый: оба элемента из первого массива. Второй: первый элемент первого массива и первый элемент второго массива. И третий: два первых элемента второго массива. В первом варианте мы просто дописываем сумму в конец второго массива. Во втором варианте мы вычеркиваем первый элемент из второго массива и добавляем его сумму с первым элементом первого массива в конец второго. Ну и в третьем варианте, мы вычеркиваем два первых элемента второго массива и добавляем их сумму в конец этого массива. Если в первом массиве элементы закончились, а во втором осталось больше одного элемента, то они меняются ролями.&lt;br /&gt;
&lt;br /&gt;
В алгоритме происходит ровно &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; итерации, так как на каждой итерации количество элементов  уменьшается ровно на один, а минимум из 4-х элементов мы выбираем за константное время.&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:KKutirev&amp;diff=33812</id>
		<title>Обсуждение участника:KKutirev</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:KKutirev&amp;diff=33812"/>
				<updated>2013-11-26T19:30:22Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: Алгоритм Хаффмана за O(n).&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Алгоритм Хаффмана за O(n). ==&lt;br /&gt;
&lt;br /&gt;
У нас есть массив частот, отсортированный по возрастанию, нужно построить по нему код Хаффмана за O(n).&lt;br /&gt;
&lt;br /&gt;
Идея алгоритма заключается в том, чтобы создать такую очередь с приоритетами, из которой можно было бы доставать два минимума O(1), после чего в эту же очередь с приоритетами положить их сумму за O(1). У нас уже есть массив с отсортированными частотами, теперь давайте заведем второй массив, в котором мы будем хранить суммы. Несложно заметить, что в этом массиве элементы тоже будут идти по неубыванию. Почему? Допустим, что на каком-то шаге сумма получилась меньше чем предыдущая, но это противоречит тому, что на каждом шаге мы выбираем два минимальных (т.е. на каждом последующем шаге мы выбираем два минимума из элементов больших, чем на предыдущем шаге).  Тогда на каждой итерации мы будет выбирать два минимума из четырех элементов (первые 2 элемента первого массива и первые 2 элемента второго массива). Теперь рассмотрим одну итерацию подробнее. У нас есть три варианта возможных пар минимумов. Первый: оба элемента из первого массива. Второй: первый элемент первого массива и первый элемент второго массива. И третий: два первых элемента второго массива. В первом варианте мы просто дописываем сумму в конец второго массива. Во втором варианте мы вычеркиваем первый элемент из второго массива и добавляем его сумму с первым элементом первого массива в конец второго. Ну и в третьем варианте, мы вычеркиваем два первых элемента второго массива и добавляем их сумму в конец этого массива. Если в первом массиве элементы закончились, а во втором осталось больше одного элемента, то они меняются ролями.&lt;br /&gt;
&lt;br /&gt;
Итак, почему же этот алгоритм работает за линейное время? В алгоритме происходит ровно n итерации, так как на каждой итерации количество элементов  уменьшается ровно на один, а минимум из 4-х элементов мы выбираем за константное время.&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33755</id>
		<title>Алгоритм Хаффмана</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=33755"/>
				<updated>2013-11-18T16:16:30Z</updated>
		
		<summary type="html">&lt;p&gt;KKutirev: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''''Алгоритм Хаффмана''''' — алгоритм оптимального префиксного кодирования алфавита. Был разработан в 1952 году аспирантом Массачусетского технологического института Дэвидом Хаффманом при написании им курсовой работы. В настоящее время используется во многих программах сжатия данных, например, для сжатия изображений он использует только частоту появления одинаковых байт в изображении. Сопоставляет символам входного потока, которые встречаются большее число раз, цепочку бит меньшей длины. И, напротив, встречающимся редко — цепочку большей длины.&lt;br /&gt;
&lt;br /&gt;
== Определение ==&lt;br /&gt;
&lt;br /&gt;
{{Определение &lt;br /&gt;
|definition=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;W=\{w_{1},w_{2},...,w_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Тогда набор бинарных кодов &amp;lt;tex&amp;gt;C=\{c_{1},c_{2},...,c_{n}\}&amp;lt;/tex&amp;gt;, такой, что:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;gt; не является префиксом для &amp;lt;tex&amp;gt;c_{j}&amp;lt;/tex&amp;gt;, при &amp;lt;tex&amp;gt;i \ne j&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Сумма &amp;lt;tex&amp;gt;\sum\limits_{i \in [1, n]} w_{i}\cdot c_{i}&amp;lt;/tex&amp;gt; минимальна. (&amp;lt;tex&amp;gt;|c_{i}|&amp;lt;/tex&amp;gt; — длина кода &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;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;
1. Составим список кодируемых символов, при этом будем рассматривать один символ как дерево, состоящее из одного элемента, весом, равным частоте появления символа в тексте.&lt;br /&gt;
&lt;br /&gt;
2. Из списка выберем два узла с наименьшим весом.&lt;br /&gt;
&lt;br /&gt;
3. Сформируем новый узел с весом, равным сумме весов выбранных узлов, и присоединим к нему два выбранных узла в качестве дочерних.&lt;br /&gt;
&lt;br /&gt;
4. Добавим к списку только что сформированный узел.&lt;br /&gt;
&lt;br /&gt;
5. Если в списке больше одного узла, то повторить пункты со второго по пятый.&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Mississippi.png|400px|thumb|right|Дерево Хаффмана для слова ''&amp;quot;Миссисипи&amp;quot;'']]&lt;br /&gt;
&lt;br /&gt;
Для примера возьмём слово ''&amp;quot;Миссисипи&amp;quot;''. Тогда алфавит будет &amp;lt;tex&amp;gt;A= \{&amp;lt;/tex&amp;gt; ''и, м, п, с'' &amp;lt;tex&amp;gt;\} &amp;lt;/tex&amp;gt;, а набор весов &amp;lt;tex&amp;gt;W=\{4, 1, 1, 3\}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 1 || 1 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
По алгоритму возьмем два символа с наименьшей частотой {{---}} это ''м'' и ''п''. Сформируем из них новый узел ''мп'' весом 2 и добавим его к списку узлов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мп || с &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 2 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Затем объединим в один узел узлы ''мп'' и ''c'':&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мпс &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 5 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
И, наконец, объединяем два узла ''и'' и ''мпс''. Итак, мы получили дерево Хаффмана и соответствующую ему таблицу кодов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Код || 0 || 100 || 101 || 11&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, закодированное слово ''&amp;quot;миссисипи&amp;quot;'' будет выглядеть как ''&amp;quot;1000111101101010&amp;quot;''. Длина закодированного слова {{---}} 16 бит. Стоит заметить, что если бы мы использовали для кодирования каждого символа из четырёх по 2 бита, длина закодированного слова составила бы 18 бит.&lt;br /&gt;
&lt;br /&gt;
== Корректность алгоритма Хаффмана ==&lt;br /&gt;
 &lt;br /&gt;
Чтобы доказать корректность алгоритма Хаффмана, покажем, что в задаче о построении оптимального префиксного кода проявляются свойства жадного выбора и оптимальной подструктуры. В сформулированной ниже лемме показано соблюдение свойства жадного выбора. &lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; — алфавит, каждый символ &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; которого встречается с частотой &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с самыми низкими частотами.&lt;br /&gt;
&lt;br /&gt;
Тогда для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; существует оптимальный префиксный код, кодовые слова символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; в котором имеют одинаковую максимальную длину и отличаются лишь последним битом. &lt;br /&gt;
|proof=&lt;br /&gt;
Возьмем дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, представляющее произвольный оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Преобразуем его в дерево, представляющее другой оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — листья с общим родительским узлом, находящиеся на максимальной глубине.&lt;br /&gt;
&lt;br /&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;T&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;f[a] \le f[b]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[x] \le f[y]&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y]&amp;lt;/tex&amp;gt; — две наименьшие частоты, а &amp;lt;tex&amp;gt;f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[b]&amp;lt;/tex&amp;gt; — две произвольные частоты, то выполняются отношения &amp;lt;tex&amp;gt;f[x] \le f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y] \le f[b]&amp;lt;/tex&amp;gt;. Пусть дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — дерево, полученное из &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; путем перестановки листьев &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, а дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево полученное из &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; перестановкой листьев &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Разность стоимостей деревьев &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; равна:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T) - B(T') = \sum\limits_{c \in C} f(c)d_T(c) - \sum\limits_{c \in C} f(c)d_{T'}(c) = (f[a] - f[x])(d_T(a) - d_T(x)),&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
что больше либо равно &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, так как величины &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; неотрицательны. Величина &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; неотрицательна, потому что &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — лист с минимальной частотой, а величина &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; является неотрицательной, так как лист &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; находится на максимальной глубине в дереве &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Точно так же перестановка листьев &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; не будет приводить к увеличению стоимости. Таким образом, разность &amp;lt;tex&amp;gt;B(T') - B(T'')&amp;lt;/tex&amp;gt; тоже будет неотрицательной.&lt;br /&gt;
&lt;br /&gt;
Таким образом, выполняется неравенство &amp;lt;tex&amp;gt;B(T'') \le B(T)&amp;lt;/tex&amp;gt;. С другой стороны, &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; — оптимальное дерево, поэтому должно выполняться неравенство &amp;lt;tex&amp;gt;B(T) \le B(T'')&amp;lt;/tex&amp;gt;. Отсюда следует, что &amp;lt;tex&amp;gt;B(T) = B(T'')&amp;lt;/tex&amp;gt;. Значит, &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево, представляющее оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; имеют одинаковую максимальную длину, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
 &lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=Пусть дан алфавит &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, в котором для каждого символа &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; определены частоты &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с минимальными частотами. Пусть &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; — алфавит, полученный из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; путем удаления символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и добавления нового символа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;, так что &amp;lt;tex&amp;gt;C' = C \backslash \{ x, y \} \cup {z}&amp;lt;/tex&amp;gt;. По определению частоты &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; в алфавите &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; совпадают с частотами в алфавите &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, за исключением частоты &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — произвольное дерево, представляющее оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; Тогда дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, полученное из дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; путем замены листа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; внутренним узлом с дочерними элементами &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof=&lt;br /&gt;
Сначала покажем, что стоимость &amp;lt;tex&amp;gt;B(T)&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; может быть выражена через стоимость &amp;lt;tex&amp;gt;B(T')&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt;. Для каждого символа &amp;lt;tex&amp;gt;c \in C \backslash \{x, y \}&amp;lt;/tex&amp;gt; верно &amp;lt;tex&amp;gt;d_T(C) = d_{T'}&amp;lt;/tex&amp;gt;, значит, &amp;lt;tex&amp;gt;f[c]d_T(c) = f[c]d_{T'}(c)&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;d_T(x) = d_T(y) = d_{T'} (z) + 1&amp;lt;/tex&amp;gt;, то&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f[x]d_T(x) + f[y]d_T(y) = (f[x] + f[y])(d_{T'}(z) + 1) = f[z]d_{T'}(z) + (f[x] + f[y])&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
из чего следует, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T) = B(T') + f[x] + f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T') = B(T) - f[x] - f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем лемму от противного. Предположим, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Тогда существует дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;B(T'') &amp;lt; B(T)&amp;lt;/tex&amp;gt;. Согласно лемме (1), элементы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; можно считать дочерними элементами одного узла. Пусть дерево &amp;lt;tex&amp;gt;T'''&amp;lt;/tex&amp;gt; получено из дерева &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; заменой элементов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; листом &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; с частотой &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Тогда&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T''') = B(T'') - f[x] - f[y] &amp;lt; B(T) - f[x] - f[y] = B(T')&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
что противоречит предположению о том, что дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt;. Значит, наше предположение о том, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, неверно, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Алгоритм Хаффмана дает оптимальный префиксный код. &lt;br /&gt;
|proof=&lt;br /&gt;
Справедливость теоремы непосредственно следует из лемм (1) и (2)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — с. 459. — ISBN 5-8489-0857-4&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Алгоритм_Хаффмана Википедия — Алгоритм Хаффмана]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Wikipedia — Huffman coding]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%C4%E2%EE%E8%F7%ED%EE%E5_%E4%E5%F0%E5%E2%EE Википедия — Бинарное дерево]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Префиксный_код Википедия — Префиксный код]&lt;br /&gt;
*[http://neerc.ifmo.ru/wiki/index.php?title=Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза Задача об оптимальном префиксном коде]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>KKutirev</name></author>	</entry>

	</feed>