📚 什么是霍夫曼编码?

霍夫曼编码是一种用于无损数据压缩的最优前缀编码算法,由 David A. Huffman 于1952年发明。

核心思想:出现频率高的字符用短编码,频率低的用长编码,从而使总编码长度最短。

🔧 构建步骤

霍夫曼树构建算法

  1. 统计频率:计算每个字符出现的次数
  2. 创建叶节点:每个字符创建一个带权值的叶节点
  3. 合并最小:每次取出两个权值最小的节点
  4. 生成新节点:合并后创建新的父节点,权值为两子节点之和
  5. 重复步骤3-4:直到只剩一个节点(根节点)

🏷️ 编码规则

根节点叶节点的路径决定编码:

  • 左分支 → 记为 0
  • 右分支 → 记为 1

每个叶节点的路径编码就是该字符的霍夫曼编码。

💡 特性

特性 说明
前缀码 任何字符的编码都不是其他字符编码的前缀
最优性 在所有前缀码中,霍夫曼编码的平均码长最短
无损压缩 可以完全还原原始数据

💻 C语言结构

typedef struct HuffmanNode { char ch; // 字符 int freq; // 频率/权值 struct HuffmanNode *left; // 左子树 struct HuffmanNode *right; // 右子树 } HuffmanNode;

✏️ 输入数据

示例:

📚 转换原理

普通树(多叉树)与二叉树之间可以相互转换,且转换是唯一的。

核心思想:左孩子右兄弟表示法

  • 二叉树的左指针 → 指向第一个孩子
  • 二叉树的右指针 → 指向右边兄弟

🔄 树 → 二叉树

转换步骤

  1. 连兄弟:将同一父节点的所有兄弟节点用线连接
  2. 删边:每个节点只保留与第一个孩子的连线,删除与其他孩子的连线
  3. 旋转:将整棵树顺时针旋转45°,使兄弟连线变成右子树

🔄 二叉树 → 树

转换步骤

  1. 连父子:若节点x是其父节点的左孩子,则将x的右孩子、右孩子的右孩子...都与x的父节点连线
  2. 删右边:删除所有节点与其右孩子的连线
  3. 整理:调整位置,使同层兄弟在同一水平线上

🌳 森林 ⟷ 二叉树

森林转二叉树:

  1. 将森林中每棵树转换为二叉树
  2. 第一棵树的根作为二叉树的根
  3. 后续每棵树的根作为前一棵树根的右孩子

二叉树转森林:

  1. 从根节点开始,沿右指针断开
  2. 将每棵子二叉树转换回普通树

💡 性质

性质 说明
右子树空 单棵树转换的二叉树,根节点右子树为空
遍历对应 树的先根 = 二叉树先序
树的后根 = 二叉树中序
可逆性 转换过程是完全可逆的

✏️ 输入树结构

格式: 节点(子节点1,子节点2,...) ,子节点可以继续嵌套
示例: