Алгоритм Хаффмана — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Корректность алгоритма Хаффмана)
Строка 28: Строка 28:
 
== Корректность алгоритма Хаффмана ==
 
== Корректность алгоритма Хаффмана ==
 
   
 
   
Чтобы доказать корректность жадного алгоритма Huffman, покажем, что в за-
+
Чтобы доказать корректность жадного алгоритма Huffman, покажем, что в задаче о построении оптимального префиксного кода проявляются свойства жадного выбора и оптимальной подструктуры. В сформулированной ниже лемме показано соблюдение свойства жадного выбора.  
даче о построении оптимального префиксного кода проявляются свойства жадного  
+
 
выбора и оптимальной подструктуры. В сформулированной ниже лемме показано  
+
{{Лемма
соблюдение свойства жадного выбора.  
+
|id=lemma1
Лемма 16.2. Пусть С — алфавит, каждый символ с€С которого встречается с ча-
+
|about=1
стотой / [с]. Пусть х и у — два символа алфавита С с самыми низкими частотами.  
+
|statement=Пусть <tex>C</tex> — алфавит, каждый символ <tex>c \in C</tex> которого встречается с частотой <tex>f[c]</tex>. Пусть <tex>x</tex> и <tex>y</tex> — два символа алфавита <tex>C</tex> с самыми низкими частотами. Тогда для алфавита <tex>C</tex> существует оптимальный префиксный код, кодовые слова символов <tex>x</tex> и <tex>y</tex> в котором имеют одинаковую длину и отличаются лишь последним битом.  
Тогда для алфавита С существует оптимальный префиксный код, кодовые слова  
+
|proof=Идея доказательства состоит в том, чтобы взять дерево <tex>T</tex>, представляющее произвольный оптимальный префиксный код, и преобразовать его в дерево, представляющее другой оптимальный префиксный код, в котором символы <tex>x</tex> и <tex>y</tex> являются листьями с общим родительским узлом, причем в новом дереве эти листья находятся на максимальной глубине. Пусть <tex>a</tex> и <tex>b</tex> — два символа, представленные листьями с общим родительским узлом, которые находятся на максимальной глубине дерева <tex>T</tex>. Предположим без потери общности, что <tex>f[a] \le f[b]</tex> и <tex>f[x] \le f[y]</tex>. Поскольку <tex>f[x]</tex> и <tex>f[y]</tex> — две самые маленькие частоты (в указанном порядке), <tex>f[a]</tex> и <tex>f[b]</tex> — две произвольные частоты, то выполняются соотношения <tex>f[x] \le f[a]</tex> и <tex>f[y] \le f[b]</tex>. В результате перестановки в дереве <tex>T</tex> листьев <tex>a</tex> и <tex>x</tex> получается дерево <tex>T'</tex>, а при последующей перестановке в дереве V листьев <tex>b</tex> и <tex>y</tex> получается дерево <tex>T''</tex>. Разность стоимостей деревьев Т и Т" равна <br>
символов х и у в котором имеют одинаковую длину и отличаются лишь последним  
+
<tex>B(T) - B(T') = \sum_{c \in C} f(c)d_T(C) - \sum_{c \in C} f(c)d_{T'}(C) =</tex><br><tex> = (f[a] - f[x])(d_T(a) - d_T(x)) \ge 0</tex>,<br>
битом.  
+
поскольку величины <tex>f[a] - f[x]</tex> и <tex>d_T(a) - d_T(x)</tex> неотрицательны. Величина <tex>f[a] - f[x]</tex> неотрицательна, потому что х — лист с минимальной частотой, величина <tex>d_T(a) - d_T(x)</tex> неотрицательна, потому что <tex>a</tex> — лист на максимальной глубине в дереве <tex>T</tex>. Аналогично, перестановка листьев <tex>y</tex> и <tex>b</tex> не приведет к увеличению стоимости, поэтому величина <tex>B(T') - B(T'')</tex> неотрицательна. Таким образом, выполняется неравенство <tex>B(T') \le B(T'')</tex>, и поскольку <tex>T</tex> — оптимальное дерево, то должно также выполняться неравенство <tex>B(T'') \le B(T')</tex>, откуда следует, что <tex>B(T') = B(T'')</tex>. Таким образом, <tex>T''</tex> — оптимальное дерево, в котором <tex>x</tex> и <tex>y</tex> — находящиеся на максимальной глубине дочерние листья одного и того же узла, что и доказывает лемму.
Доказательство. Идея доказательства состоит в том, чтобы взять дерево Т, пред-
+
}}
ставляющее произвольный оптимальный префиксный код, и преобразовать его  
+
в дерево, представляющее другой оптимальный префиксный код, в котором сим-
+
{{Лемма
волы х и у являются листьями с общим родительским узлом, причем в новом  
+
|id=lemma2.  
дереве эти листья находятся на максимальной глубине.  
+
|about=2
Пусть а и b — два символа, представленные листьями с общим родительским  
+
|statement=Пусть дан алфавит <tex>C</tex>, в котором для каждого символа <tex>c \in C</tex> определены частоты <tex>f[c]</tex>. Пусть <tex>x</tex> и <tex>y</tex> — два символа из алфавита <tex>C</tex> с минимальными частотами. Пусть <tex>C'</tex> — алфавит, полученный из алфавита <tex>C</tex> путем удаления символов <tex>x</tex> и <tex>y</tex> и добавления нового символа <tex>z</tex>, так что <tex>C = C — {х,у} \cup {z}</tex>. По определению частоты <tex>f</tex> в алфавите <tex>C'</tex> совпадают с частотами в алфавите <tex>C</tex>, за исключением частоты <tex>f[z] = f[x] + f[y]</tex>. Пусть <tex>T'</tex> — произвольное дерево, представляющее оптимальный префиксный код для алфавита <tex>C'</tex> Тогда дерево <tex>T</tex>, полученное из дерева <tex>T'</tex> путем замены листа <tex>z</tex> внутренним узлом с дочерними элементами <tex>x</tex> и <tex>y</tex>, представляет оптимальный префиксный код для алфавита <tex>C</tex>.  
узлом, которые находятся на максимальной глубине дерева Т. Предположим без  
+
|proof=Сначала покажем, что стоимость <tex>B(T)</tex> дерева <tex>T</tex> можно выразить через стоимость <tex>B(T')</tex> дерева <tex>T'</tex>. Для каждого символа <tex>c \le C - {x,y}</tex> выполняется соотношение <tex>d_T(C) = d_{T'}(c)</tex>, следовательно, <tex>f[c]d_T(C) = f[c]d_{T'}(c)</tex>. Поскольку <tex>d_T(x) = d_{T}(y) = d_{t'}(z) + 1</tex>, получаем соотношение<br>
потери общности, что / [а] ^ / [Ь] и / [х] ^ / [у]. Поскольку / [х] и / [у] — две  
+
<tex>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])</tex>
самые маленькие частоты (в указанном порядке), а / [а] и / [6] — две произвольные  
+
<br>
частоты, то выполняются соотношения f[x]^f [а] и / [у] ^ / [6]. Как показано
+
из которого следует равенство <br>
на рис. 16.5, в результате перестановки в дереве Т листьев а и х получается дерево  
+
<tex> B(T) = B(T') + f[x] + f[y] </tex> <br>
Т", а при последующей перестановке в дереве V листьев Ь и у получается дерево  
+
ИЛИ <br>
Т". Согласно уравнению A6.5), разность стоимостей деревьев Т и Т" равна  
+
<tex> B(T') = B(T) - f[x] - f[y] </tex>. <br>
В(Т)-В (Г') = ?/(c)dr (с) - ?/(c)(fev (с) =  
+
Докажем лемму методом от противного. Предположим, дерево <tex> T </tex> не представляет оптимальный префиксный код для алфавита <tex> C </tex>. Тогда существует дерево <tex> T'' </tex>, для которого справедливо неравенство <tex> B(T'') < B(T) </tex>. Согласно лемме (1), <tex>x</tex> и <tex>y</tex> без потери общности можно считать дочерними элементами одного и того же узла. Пусть дерево <tex>T'''</tex> получено из дерева <tex>T''</tex> путем замены элементов <tex>x</tex> и <tex>y</tex> листом <tex>z</tex> с частотой <tex>f[z] = f[x] + f[y] </tex>. Тогда можно записать:<br>
сес сес = f [x] dT (х) + f [a] dT (а) - f [x] dT, (х) - / [a] dT> (а) = = / [х] dT (х) + / [a] dT (а) - / [х] dT (а) - / [а] dT (x) = = (f[a]-f[x})(dT(a)-dT(x))>0,  
+
<tex>B(T''') = B(T'') - f[x] - f[y] < B(T) - f[x] -f[y] = B(T')</tex>,<br>
поскольку величины / [а]-/ [х] и йт (aj—dr (x) неотрицательны. Величина / [а]
+
что противоречит предположению о том, что дерево <tex>T'</tex> представляет оптимальный префиксный код для алфавита <tex>C'</tex>. Таким образом, дерево <tex>T</tex> должно представлять оптимальный префиксный код для алфавита <tex>C</tex>. 
- f [х] неотрицательна, потому что х — лист с минимальной частотой, величина  
+
}}
(о) — dr (x) неотрицательна, потому что а — лист на максимальной глубине  
+
 
Глава 16. Жадные алгоритмы 465
+
Лемма 16.3.
Рис. 16.5. Иллюстрация ключевых этапов доказательства леммы 16.2
+
Доказательство.  
в дереве Т. Аналогично, перестановка листьев у и b не приведет к увеличению  
 
стоимости, поэтому величина В (Т") — В (Т") неотрицательна. Таким образом,  
 
выполняется неравенство В (Г") ^ В (Т), и поскольку Т — оптимальное дерево,  
 
то должно также выполняться неравенство В (Т) < В (Т"), откуда следует, что  
 
В {Т") = В (Т). Таким образом, Т" — оптимальное дерево, в котором х и у —  
 
находящиеся на максимальной глубине дочерние листья одного и того же узла,  
 
что и доказывает лемму. д
 
Из леммы 16.2 следует, что процесс построения оптимального дерева путем
 
объединения узлов без потери общности можно начать с жадного выбора, при
 
котором объединению подлежат два символа с наименьшими частотами. Почему
 
такой выбор будет жадным? Стоимость объединения можно рассматривать как
 
сумму частот входящих в него элементов. В упражнении 16.3-3 предлагается
 
показать, что полная стоимость сконструированного таким образом дерева равна
 
сумме стоимостей его составляющих. Из всевозможных вариантов объединения
 
на каждом этапе в процедуре Huffman выбирается тот, в котором получается
 
минимальная стоимость.
 
В приведенной ниже лемме показано, что задача о составлении оптимальных
 
префиксных кодов обладает свойством оптимальной подструктуры.
 
Лемма 16.3. Пусть дан алфавит С, в котором для каждого символа се С опре-
 
делены частоты / [с]. Пусть х иу — два символа из алфавита С с минимальными  
 
частотами. Пусть С — алфавит, полученный из алфавита С путем удаления сим-
 
волов х и у и добавления нового символа z, так что С = С — {х,у} U {z}.  
 
По определению частоты / в алфавите С совпадают с частотами в алфавите С,  
 
за исключением частоты / [z] = f [x] + / [у]. Пусть Т" — произвольное дерево,  
 
представляющее оптимальный префиксный код для алфавита С Тогда дерево Г,  
 
полученное из дерева Т" путем замены листа z внутренним узлом с дочерними  
 
элементами х и у, представляет оптимальный префиксный код для алфавита С.  
 
Доказательство. Сначала покажем, что стоимость В (Г) дерева Г можно выра-
 
зить через стоимость В (Т") дерева Т", рассматривая стоимости компонентов из
 
уравнения A6.5). Для каждого символа се С — {х,у} выполняется соотношение  
 
466 Часть IV. Усовершенствованные методы разработки и анализа
 
Aт {с) = йт' (с), следовательно, /[с](с) = /[c]d^'(c). Поскольку dr (#) =  
 
= dr (у) = dr' B:) + 1, получаем соотношение  
 
/ [х] dT (х) + f [у] dT (у) = (/ [х] + f {у}) {dT> (z) + 1) =
 
из которого следует равенство  
 
B(T) = B(T')+f[x)
 
ИЛИ  
 
B{T')=B(T)-f[x]-f[y].  
 
Докажем лемму методом от противного. Предположим, дерево Т не представ-
 
ляет оптимальный префиксный код для алфавита С Тогда существует дерево Т",  
 
для которого справедливо неравенство В(Т") < В{Т). Согласно лемме 16.2, х
 
и у без потери общности можно считать дочерними элементами одного и того  
 
же узла. Пусть дерево Т"' получено из дерева Т" путем замены элементов х и у
 
листом z с частотой / [z] = / [х] + f [у]. Тогда можно записать:  
 
B(T"')=B{T")-f[x}-f{y}<B(T)-f[x}-f[y} = B(T'),  
 
что противоречит предположению о том, что дерево Т' представляет оптимальный  
 
префиксный код для алфавита С. Таким образом, дерево Г должно представлять  
 
оптимальный префиксный код для алфавита С. ?
 
 
{{Теорема
 
{{Теорема
 
|id=th1
 
|id=th1
Строка 110: Строка 62:
 
Процедура Huffman дает оптимальный префиксный код.  
 
Процедура Huffman дает оптимальный префиксный код.  
 
|proof=
 
|proof=
Справедливость теоремы непосредственно следует из лемм 1 и 2
+
Справедливость теоремы непосредственно следует из лемм (1) и (2)
 
}}
 
}}

Версия 09:41, 29 октября 2010

Определение

Определение:
Коды или Алгоритм Хаффмана (Huffman codes) — широко распространенный и очень эффективный метод сжатия данных, который, в зависимости от характеристик этих данных, обычно позволяет сэкономить от 20% до 90% объема.

Рассматриваются данные, представляющие собой последовательность символов. В жадном алгоритме Хаффмана используется таблица, содержащая частоты появления тех или иных символов. С помощью этой таблицы определяется оптимальное представление каждого символа в виде бинарной строки.

Построение кода Хаффмана

Хаффман изобрел жадный алгоритм, позволяющий составить оптимальный префиксный код, который получил название код Хаффмана. Доказательство корректности этого алгоритма основывается на свойстве жадного выбора и оптимальной подструктуре. Вместо того чтобы демонстрировать, что эти свойства выполняются, а затем разрабатывать псевдокод, сначала мы представим псевдокод. Это поможет прояснить, как алгоритм осуществляет жадный выбор. В приведенном ниже псевдокоде предполагается, что [math]C[/math] — множество, состоящее из [math]n[/math] символов, и что каждый из символов [math]c\in C[/math] — объект с определенной частотой [math]f(c)[/math]. В алгоритме строится дерево [math]T[/math], соответствующее оптимальному коду, причем построение идет в восходящем направлении. Процесс построения начинается с множества, состоящего из [math]|C|[/math] листьев, после чего последовательно выполняется [math]|C|-1[/math] операций "слияния", в результате которых образуется конечное дерево. Для идентификации двух наименее часто встречающихся объектов, подлежащих слиянию, используется очередь с приоритетами [math]Q[/math], ключами в которой являются частоты [math]f[/math]. В результате слияния двух объектов образуется новый объект, частота появления которого является суммой частот объединенных объектов:

Huffman([math]C[/math])
[math]n \gets |C|[/math]
[math]Q \gets C[/math]
for [math]i \gets 1[/math] to [math]n - 1[/math]

do Выделить память для узла [math]z[/math]
left[[math] z[/math]][math] \gets x \gets[/math] Extract_Min([math] Q[/math])
right[[math]z[/math]][math]\gets y \gets [/math] Extract_Min([math]Q[/math])
[math]f[z] \gets f[x]+f[y][/math]
Insert([math]Q[/math], [math]z[/math] )

return Extract_Min([math]Q[/math] ) [math] \rhd [/math] Возврат корня дерева

Пример работы алгоритма

Huffman.jpg
На каждом этапе показано содержимое очереди, элементы которой рассортированы в порядке возрастания их частот. На каждом шаге работы алгоритма объединяются два объекта (дерева) с самыми низкими частотами. Листья изображены в виде прямоугольников, в каждом из которых указана буква и соответствующая ей частота. Внутренние узлы представлены кругами, содержащими сумму частот дочерних узлов. Ребро, соединяющее внутренний узел с левым дочерним узлом, имеет метку 0, а ребро, соединяющее его с правым дочерним узлом, — метку 1. Слово кода для буквы образуется последовательностью меток на ребрах, соединяющих корень с листом, представляющим эту букву. По скольку данное множество содержит шесть букв, размер исходной очереди равен 6(часть а рисунка), а для построения дерева требуется пять слияний. Промежуточные этапы изображены в частях б-д. Конечное дерево (е) представляет оптимальный префиксный код. Как уже говорилось, слово кода для буквы — это последовательность меток на пути от корня к листу с этой буквой.
В строке 2 инициализируется очередь с приоритетами [math]Q[/math], состоящая из элементов множества [math]С[/math]. Цикл for в строках 3-8 поочередно извлекает по два узла, [math]x[/math] и [math]у[/math], которые характеризуются в очереди наименьшими частотами, и заменяет их в очереди новым узлом, представляющим объединение упомянутых выше элементов. Частота появления [math]z[/math] вычисляется в строке 7 как сумма частот [math]x[/math] и [math]y[/math]. Узел [math]x[/math] является левым дочерним узлом [math]z[/math], а [math]y[/math] — его правым дочерним узлом. (Этот порядок является произвольным; перестановка левого и правого дочерних узлов приводит к созданию другого кода с той же стоимостью.) После [math]n - 1[/math] объединений в очереди остается один узел — корень дерева кодов, который возвращается в строке 9.

Оценка времени работы

При анализе времени работы алгоритма Хаффмана предполагается, что [math]Q[/math] реализована как бинарная неубывающая пирамида. Для множества [math]C[/math], состоящего из [math]n[/math] символов, инициализацию очереди [math]Q[/math] в строке 2 можно выполнить за время [math]O(n)[/math]. Цикл for в строках 3-8 выполняется ровно [math]n - 1[/math] раз, и поскольку для каждой операции над пирамидой требуется время[math]O(lg(n))[/math], вклад цикла во время работы алгоритма равен [math]O(n \cdot lg(n))[/math]. Таким образом, полное время работы процедуры Huffman с входным множеством, состоящим из [math]n[/math] символов, равно [math]O(n \cdot lg(n))[/math].

Корректность алгоритма Хаффмана

Чтобы доказать корректность жадного алгоритма Huffman, покажем, что в задаче о построении оптимального префиксного кода проявляются свойства жадного выбора и оптимальной подструктуры. В сформулированной ниже лемме показано соблюдение свойства жадного выбора.

Лемма (1):
Пусть [math]C[/math] — алфавит, каждый символ [math]c \in C[/math] которого встречается с частотой [math]f[c][/math]. Пусть [math]x[/math] и [math]y[/math] — два символа алфавита [math]C[/math] с самыми низкими частотами. Тогда для алфавита [math]C[/math] существует оптимальный префиксный код, кодовые слова символов [math]x[/math] и [math]y[/math] в котором имеют одинаковую длину и отличаются лишь последним битом.
Доказательство:
[math]\triangleright[/math]

Идея доказательства состоит в том, чтобы взять дерево [math]T[/math], представляющее произвольный оптимальный префиксный код, и преобразовать его в дерево, представляющее другой оптимальный префиксный код, в котором символы [math]x[/math] и [math]y[/math] являются листьями с общим родительским узлом, причем в новом дереве эти листья находятся на максимальной глубине. Пусть [math]a[/math] и [math]b[/math] — два символа, представленные листьями с общим родительским узлом, которые находятся на максимальной глубине дерева [math]T[/math]. Предположим без потери общности, что [math]f[a] \le f[b][/math] и [math]f[x] \le f[y][/math]. Поскольку [math]f[x][/math] и [math]f[y][/math] — две самые маленькие частоты (в указанном порядке), [math]f[a][/math] и [math]f[b][/math] — две произвольные частоты, то выполняются соотношения [math]f[x] \le f[a][/math] и [math]f[y] \le f[b][/math]. В результате перестановки в дереве [math]T[/math] листьев [math]a[/math] и [math]x[/math] получается дерево [math]T'[/math], а при последующей перестановке в дереве V листьев [math]b[/math] и [math]y[/math] получается дерево [math]T''[/math]. Разность стоимостей деревьев Т и Т" равна
[math]B(T) - B(T') = \sum_{c \in C} f(c)d_T(C) - \sum_{c \in C} f(c)d_{T'}(C) =[/math]
[math] = (f[a] - f[x])(d_T(a) - d_T(x)) \ge 0[/math],

поскольку величины [math]f[a] - f[x][/math] и [math]d_T(a) - d_T(x)[/math] неотрицательны. Величина [math]f[a] - f[x][/math] неотрицательна, потому что х — лист с минимальной частотой, величина [math]d_T(a) - d_T(x)[/math] неотрицательна, потому что [math]a[/math] — лист на максимальной глубине в дереве [math]T[/math]. Аналогично, перестановка листьев [math]y[/math] и [math]b[/math] не приведет к увеличению стоимости, поэтому величина [math]B(T') - B(T'')[/math] неотрицательна. Таким образом, выполняется неравенство [math]B(T') \le B(T'')[/math], и поскольку [math]T[/math] — оптимальное дерево, то должно также выполняться неравенство [math]B(T'') \le B(T')[/math], откуда следует, что [math]B(T') = B(T'')[/math]. Таким образом, [math]T''[/math] — оптимальное дерево, в котором [math]x[/math] и [math]y[/math] — находящиеся на максимальной глубине дочерние листья одного и того же узла, что и доказывает лемму.
[math]\triangleleft[/math]
Лемма (2):
Пусть дан алфавит [math]C[/math], в котором для каждого символа [math]c \in C[/math] определены частоты [math]f[c][/math]. Пусть [math]x[/math] и [math]y[/math] — два символа из алфавита [math]C[/math] с минимальными частотами. Пусть [math]C'[/math] — алфавит, полученный из алфавита [math]C[/math] путем удаления символов [math]x[/math] и [math]y[/math] и добавления нового символа [math]z[/math], так что [math]C = C — {х,у} \cup {z}[/math]. По определению частоты [math]f[/math] в алфавите [math]C'[/math] совпадают с частотами в алфавите [math]C[/math], за исключением частоты [math]f[z] = f[x] + f[y][/math]. Пусть [math]T'[/math] — произвольное дерево, представляющее оптимальный префиксный код для алфавита [math]C'[/math] Тогда дерево [math]T[/math], полученное из дерева [math]T'[/math] путем замены листа [math]z[/math] внутренним узлом с дочерними элементами [math]x[/math] и [math]y[/math], представляет оптимальный префиксный код для алфавита [math]C[/math].
Доказательство:
[math]\triangleright[/math]

Сначала покажем, что стоимость [math]B(T)[/math] дерева [math]T[/math] можно выразить через стоимость [math]B(T')[/math] дерева [math]T'[/math]. Для каждого символа [math]c \le C - {x,y}[/math] выполняется соотношение [math]d_T(C) = d_{T'}(c)[/math], следовательно, [math]f[c]d_T(C) = f[c]d_{T'}(c)[/math]. Поскольку [math]d_T(x) = d_{T}(y) = d_{t'}(z) + 1[/math], получаем соотношение
[math]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])[/math]
из которого следует равенство
[math] B(T) = B(T') + f[x] + f[y] [/math]
ИЛИ
[math] B(T') = B(T) - f[x] - f[y] [/math].
Докажем лемму методом от противного. Предположим, дерево [math] T [/math] не представляет оптимальный префиксный код для алфавита [math] C [/math]. Тогда существует дерево [math] T'' [/math], для которого справедливо неравенство [math] B(T'') \lt B(T) [/math]. Согласно лемме (1), [math]x[/math] и [math]y[/math] без потери общности можно считать дочерними элементами одного и того же узла. Пусть дерево [math]T'''[/math] получено из дерева [math]T''[/math] путем замены элементов [math]x[/math] и [math]y[/math] листом [math]z[/math] с частотой [math]f[z] = f[x] + f[y] [/math]. Тогда можно записать:
[math]B(T''') = B(T'') - f[x] - f[y] \lt B(T) - f[x] -f[y] = B(T')[/math],

что противоречит предположению о том, что дерево [math]T'[/math] представляет оптимальный префиксный код для алфавита [math]C'[/math]. Таким образом, дерево [math]T[/math] должно представлять оптимальный префиксный код для алфавита [math]C[/math].
[math]\triangleleft[/math]

Лемма 16.3. Доказательство.

Теорема:
Процедура Huffman дает оптимальный префиксный код.
Доказательство:
[math]\triangleright[/math]
Справедливость теоремы непосредственно следует из лемм (1) и (2)
[math]\triangleleft[/math]