Huffman-Compressor

基于霍夫曼编码实现的无损文件压缩与解压缩工具,使用C++编写,核心逻辑遵循霍夫曼编码的经典实现思路,支持任意类型文件的压缩和解压操作。

项目简介

霍夫曼编码是一种基于字符频率的可变长度前缀编码算法,本项目通过C++模板实现通用的霍夫曼树结构,完成文件的压缩(将字符替换为最短编码)与解压缩(通过编码还原原始字符),全程保证数据无损。

核心特性

  • ✅ 无损压缩/解压缩:支持文本、二进制、图片等任意格式文件
  • ✅ 通用模板设计:霍夫曼节点/树采用模板实现,适配不同字符/权重类型
  • ✅ 内存安全:递归释放霍夫曼树节点,避免内存泄漏
  • ✅ 命令行交互:简单的控制台交互流程,无需复杂参数
  • ✅ 完整元数据存储:压缩文件包含原始文件大小、字符频率表,确保解压准确性

编译与运行

环境要求

  • 支持C++11及以上标准的编译器(GCC、Clang、MSVC等)
  • 任意操作系统(Windows/Linux/macOS)

编译命令

# GCC/Clang
g++ HuffCode.cpp -o huffman -std=c++11

# Windows MSVC (Developer Command Prompt)
cl HuffCode.cpp /EHsc /Fe:huffman.exe

运行程序

# 编译后直接执行
./huffman  # Linux/macOS
huffman.exe  # Windows

使用说明

程序运行后会进入交互界面,按提示操作即可:

1. 压缩文件

请选择操作: 1. 压缩 2. 解压缩
1
请输入源文件名:test.txt
请输入目标文件:test.huff
这在处理中,请等待………
处理结束
  • 源文件:待压缩的原始文件路径(相对/绝对路径均可)
  • 目标文件:压缩后的文件路径(建议使用.huff后缀区分)

2. 解压缩文件

请选择操作: 1. 压缩 2. 解压缩
2
请输入压缩文件名:test.huff
请输入目标文件:test_restore.txt
这在解压中,请等待………
处理结束
  • 压缩文件:之前生成的.huff格式文件
  • 目标文件:解压后的原始文件路径

核心实现说明

1. 霍夫曼节点设计

  • HuffNode:抽象基类,定义节点核心接口(获取权重、判断叶子节点、左右子节点操作)
  • LeafNode:叶子节点,存储字符和对应权重
  • InNode:内部节点,存储权重和左右子节点指针,析构时递归释放子节点

2. 霍夫曼树构建

  • 小顶堆(优先队列)实现:按权重升序排列节点,每次取最小的两个节点合并
  • 编码生成:递归遍历霍夫曼树,为每个叶子节点生成唯一的0/1编码
  • 字符索引映射:将字符转换为0-255的索引,确保编码存储的唯一性

3. 压缩文件结构

压缩后的文件包含三部分: | 部分 | 说明 | 数据类型 | |---------------|--------------------------|-------------------| | 原始文件大小 | 记录原始文件的字节数 | unsigned long | | 字符频率表 | 256个字符的出现次数 | unsigned long[256]| | 编码数据 | 霍夫曼编码后的二进制数据 | 字节流(补0对齐) |

4. 压缩/解压流程

  • 压缩:统计字符频率 → 构建霍夫曼树 → 生成字符编码 → 写入元数据 + 编码后数据
  • 解压:读取元数据 → 重建霍夫曼树 → 解析编码数据 → 还原原始字符

注意事项

  1. 空文件处理:程序会检测空文件并直接退出,避免无效操作
  2. 路径问题:输入文件路径时确保正确,相对路径以程序运行目录为基准
  3. 小文件开销:小文件的压缩效果可能不明显(元数据占比过高),适合大文件压缩
  4. 编码唯一性:基于字符频率生成的霍夫曼编码保证前缀唯一,无解码歧义

常见问题

Q:压缩后的文件比原文件大?

A:霍夫曼编码的压缩效果依赖字符重复度,小文件/字符分布均匀的文件(如加密文件)可能出现元数据开销 > 压缩收益的情况,属于正常现象。

Q:解压后文件与原文件不一致?

A:请确保压缩/解压使用同一版本程序,且压缩文件未被修改(元数据损坏会导致解压异常)。

Q:程序运行时崩溃?

A:检查文件路径是否正确、文件是否被占用,或尝试使用绝对路径输入文件名。

许可证

本项目为开源学习用途,无明确许可证限制,可自由修改、分发和使用。

学习参考

本项目适合学习霍夫曼编码的核心原理:

  • 贪心算法在霍夫曼树构建中的应用
  • 优先队列(小顶堆)的使用
  • 模板类/抽象类的设计与实现
  • 文件二进制读写与字节操作
  • 递归算法在树结构中的应用