Задания № 11, 14 · ЕГЭ

Кодирование Хаффмана

Как построить префиксный код, используя частоты символов
6 мин чтенияСложность: Обновлено 29 сентября 2026

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

Основная идея и термины

Пусть сообщение состоит из символов алфавита \(a_1,a_2,\ldots,a_n\). Для каждого символа известна его частота — число появлений в сообщении или вероятность появления. Нужно сопоставить символам двоичные кодовые слова так, чтобы сообщение занимало как можно меньше битов.

D
Код Хаффмана

Код Хаффмана — двоичный префиксный код, построенный по частотам символов с помощью последовательного объединения двух наименее частых элементов. Он является оптимальным среди двоичных префиксных кодов для заданных частот.

Префиксный код обладает важным свойством: ни одно кодовое слово не является началом другого. Поэтому декодирование выполняется слева направо без разделителей. Кодовое дерево представляет такой код: каждому переходу влево или вправо приписывают 0 или 1, а символы размещают в листьях.

Если символ находится на глубине \(l_i\), то его код имеет длину \(l_i\). Средняя длина кодирования одного символа определяется частотами \(p_i\) и длинами кодов.

\[L=\sum_{i=1}^{n}p_i l_i\]1

Если вместо вероятностей даны количества появлений \(f_i\), можно использовать взвешенную сумму длин. Общее число битов равно сумме произведений частоты на длину кода.

\[B=\sum_{i=1}^{n}f_i l_i\]2
T
Правило Хаффмана

Для построения кода Хаффмана два символа или узла с наименьшими частотами объединяют в один узел с суммарной частотой. Процесс повторяют, пока не останется один корневой узел. Затем по ветвям дерева выписывают двоичные коды.

Алгоритм построения

Алгоритм можно выполнять в таблице. На каждом шаге выбирайте два минимальных значения, складывайте их и возвращайте сумму в список. Важно сохранять структуру объединения: простого списка частот недостаточно, потому что в конце нужно восстановить коды.

  1. Запишите все символы и их частоты.
  2. Выберите два узла с наименьшими частотами.
  3. Объедините их в новый узел с частотой, равной сумме.
  4. Повторяйте действия, пока не получится один узел — корень дерева.
  5. Назначьте ветвям значения 0 и 1 и прочитайте код каждого символа от корня к листу.
1046ABCD010101
Пример двоичного дерева: символы находятся только в листьях, а код задаётся последовательностью меток на ветвях.
Как выбирать 0 и 1

Не имеет значения, какой из двух братьев помечен 0, а какой 1. Если поменять метки у ветвей, получится другой код с теми же длинами и той же эффективностью.

Разобранный пример

Построим код для символов \(A\), \(B\), \(C\), \(D\) с частотами соответственно 5, 7, 10 и 15. На каждом шаге объединяем два наименьших узла.

1
Сначала выбираем две минимальные частоты: 5 и 7.
5+7=12
2
В списке остаются 10, 12 и 15. Объединяем 10 и 12.
10+12=22
3
В списке остаются 15 и 22. Объединяем их и получаем корень.
15+22=37
4
Назначим меньшей ветви 0, большей 1. Тогда \(D\) получает код 0, \(C\) — 10, а \(A\) и \(B\) — 110 и 111.
\(\displaystyle A\to110,\quad B\to111,\quad C\to10,\quad D\to0\)
5
Проверим среднюю длину по общей частоте 37.
\(\displaystyle B=5\cdot3+7\cdot3+10\cdot2+15\cdot1=76\ \text{бит}\)
6
Средняя длина одного символа получается делением общего числа битов на число символов.
\(\displaystyle L=\frac{76}{37}\approx2{,}05\ \text{бита}\)
№
Проверка декодирования

Закодируем строку \(CAD\): \(C\to10\), \(A\to110\), \(D\to0\), поэтому получится \(101100\). Читаем поток слева: \(10|110|0\). Ни один код не приходится разделять догадкой, так как код префиксный.

Проверь себя

Какие два узла нужно объединить на первом шаге для частот 3, 8, 5 и 2?

Почему код получается эффективным

Частый символ выгодно поместить ближе к корню: тогда его код короче и он вносит меньший вклад в общее число битов. Редкий символ может находиться глубже, потому что его длинный код используется реже.

T
Свойство оптимальности

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

Для сравнения с равномерным кодом найдите число символов \(n\) и оцените длину фиксированного кода как \(\lceil\log_2 n\rceil\) бит на символ. Хаффман может быть выгоднее, если частоты заметно различаются. При одинаковых частотах выигрыш обычно отсутствует или невелик.

Код Хаффмана не шифрует данные: частоты и способ построения могут раскрывать особенности сообщения. Его цель — сжатие информации, а не защита от чтения.

Что нужно уметь в задачах

  • Находить два наименьших значения на каждом шаге.
  • Строить дерево объединений и подписывать ветви 0 и 1.
  • Выписывать код символа по пути от корня к листу.
  • Проверять, что кодовые слова не являются префиксами друг друга.
  • Считать длину закодированного сообщения по формуле \(B=\sum f_i l_i\).
  • Сравнивать результат с равномерным или другим кодом.
!
Частые ошибки

Не объединяйте самые частые символы: выбираются два минимальных значения. Не путайте частоту с длиной кода: большая частота обычно приводит к меньшей длине, но не задаёт её напрямую. Не забывайте учитывать все появления символа в формуле общего объёма. При совпадении частот возможны разные деревья — это не обязательно ошибка. Наконец, код одного символа в строке нельзя искать по частям произвольно: декодирование идёт от корня дерева.

Запомнить

Два минимальных узла → объединение → повторение до корня → метки 0 и 1 → чтение кодов от корня к листьям.

Связь с другими способами кодирования

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

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

Q
Быстрый тест по теме

Итоговая проверка

~ 2 мин4 вопроса
Вопрос 1 / 4
Вопрос 1 из 4 · алгоритм
Какой принцип используется при построении дерева Хаффмана?
Главное за минуту

Главное

  • Код Хаффмана строится по частотам символов и является двоичным префиксным кодом.
  • На каждом шаге объединяются два узла с наименьшими частотами.
  • Код символа — путь от корня дерева к соответствующему листу; метки ветвей 0 и 1.
  • Объём закодированного сообщения вычисляется как \(B=\sum f_i l_i\), а средняя длина — как \(L=\sum p_i l_i\).
  • Разные варианты нумерации ветвей могут давать разные слова, но одинаковую эффективность.