Структуры данных

Узел дерева

Каждый узел дерева Хаффмана содержит:

  • Листья содержат конкретный символ и его исходную частоту.
  • Внутренние узлы имеют symbol == '\0' и freq = left->freq + right->freq.

 

Порядок в очереди с приоритетом

 

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

  • Step 1 collects frequencies in a hash map.
  • Step 2 seeds the priority queue with leaf nodes.
  • Step 3 repeatedly extracts two smallest‐weight nodes, merges them under a new internal node, and reinserts—ultimately yielding a single root.

 

Генерация таблицы кодов

После постройки дерева, обход в глубину присваивает каждому символу строку битов:

  • В листьях сохраняем накопленную битовую строку.
  • В внутренних узлах рекурсивно продолжаем обход, наращивая префикс.

 

Сборка итоговой программы

Вывод должен быть примерно таким:

  Codewords:
'A': 0
'B': 110
'C': 101
'D': 111
'E': 100
  

 

Временная сложность

Общая сложность алгоритма Хаффмана складывается из этапов:

Подсчёт частот

Проход по входной строке длины $N$ за $O(N)$.

Построение кучи

Вставка $n$ уникальных символов в кучу за $O(n \log n)$.

Слияние деревьев

Выполняется $n−1$ шаг, каждый — три операции кучи по $O(log⁡n)$, итого $O(nlog⁡n)$.

Извлечение кодов

Обход всех узлов (количество узлов $\approx 2n−1$) за $O(n)$.

Итоговая оценка

$$ O(N)+O(n \log n)+O(n \log n)+O(n)=O(N+n \log n) $$

  • Если алфавит фиксирован (ASCII, Unicode), $n$ считается константой, и сложность упрощается до $O(N)$.
  • В худшем случае, когда $n=N$, получаем $O(N \log ⁡N)$.

Таким образом алгоритм масштабируется почти линейно и остаётся эффективным для больших данных с умеренно большим алфавитом.

 

Код на GitHub

Код реализации алгоритма Хаффмана

Last updated 09 мая 2025, 23:43 +0500 . history