哈夫曼编码和哈夫曼树

哈夫曼编码(Huffman Coding) 是一种基于字符出现频率的无损数据压缩算法,通过构建哈夫曼树(Huffman Tree) 来生成最优前缀编码,使得高频字符用短编码,低频字符用长编码,从而实现高效压缩。


1. 哈夫曼树(Huffman Tree)

  • 定义:哈夫曼树是一棵带权路径长度(WPL)最小的二叉树。
    • 权值:字符的出现频率(或概率)。
    • 带权路径长度:每个叶子节点的权值 × 其到根节点的路径长度之和。
  • 特点
    • 没有度为1的节点(严格的二叉树)。
    • 频率越高的字符离根越近,编码越短。
构建哈夫曼树的步骤
  1. 统计字符频率:为每个字符赋予权值(频率)。
  2. 创建节点集合:每个字符作为一个叶子节点,组成初始森林。
  3. 合并最小权值节点
    • 每次选择权值最小的两个节点,合并成一个新父节点,权值为两者之和。
    • 重复合并,直到只剩一棵树。
  4. 生成编码:从根到叶子的路径,左分支为 0,右分支为 1(或相反)。

示例
假设字符 A(5), B(9), C(12), D(13), E(16), F(45)
构建过程如下:

  1. 初始节点集合:5, 9, 12, 13, 16, 45
  2. 合并最小的 59 → 新节点 14
  3. 合并 1213 → 新节点 25
  4. 合并 1416 → 新节点 30
  5. 合并 2530 → 新节点 55
  6. 合并 4555 → 根节点 100
    最终哈夫曼树结构如下:
         (100)/       \F(45)     (55)/      \(25)      (30)/    \     /   \C(12)   D(13)(14)  E(16)/ \A(5) B(9)

2. 哈夫曼编码(Huffman Coding)

  • 规则:从根到叶子节点的路径生成二进制编码。
    • 左分支为 0,右分支为 1(或相反)。
  • 示例(基于上述哈夫曼树):
    • F(45)0
    • C(12)100
    • D(13)101
    • A(5)1100
    • B(9)1101
    • E(16)111
编码特点
  1. 前缀码(Prefix Code):任何字符的编码都不是其他编码的前缀,避免解码歧义。
  2. 最优性:在所有前缀码中,哈夫曼编码的压缩效率最高(WPL最小)。

3. 哈夫曼编码的压缩与解压

压缩过程
  1. 统计字符频率,构建哈夫曼树。
  2. 生成字符到二进制编码的映射表。
  3. 将原始数据替换为哈夫曼编码的二进制流。
解压过程
  1. 根据哈夫曼树或编码表,从二进制流中逐位解码。
  2. 从根节点开始,根据 0/1 向左/右子树移动,直到到达叶子节点,输出对应字符。

4. 代码实现(C++ 示例)

#include <iostream>
#include <queue>
#include <unordered_map>
using namespace std;// 哈夫曼树节点
struct Node {char ch;int freq;Node *left, *right;Node(char c, int f) : ch(c), freq(f), left(nullptr), right(nullptr) {}
};// 优先队列的比较器(按频率升序)
struct Compare {bool operator()(Node* a, Node* b) {return a->freq > b->freq;}
};// 构建哈夫曼树
Node* buildHuffmanTree(const unordered_map<char, int>& freqMap) {priority_queue<Node*, vector<Node*>, Compare> pq;for (auto& pair : freqMap) {pq.push(new Node(pair.first, pair.second));}while (pq.size() > 1) {Node* left = pq.top(); pq.pop();Node* right = pq.top(); pq.pop();Node* parent = new Node('\0', left->freq + right->freq);parent->left = left;parent->right = right;pq.push(parent);}return pq.top();
}// 生成编码表
void generateCodes(Node* root, string code, unordered_map<char, string>& codes) {if (!root) return;if (root->ch != '\0') {codes[root->ch] = code;return;}generateCodes(root->left, code + "0", codes);generateCodes(root->right, code + "1", codes);
}int main() {unordered_map<char, int> freqMap = {{'A',5}, {'B',9}, {'C',12}, {'D',13}, {'E',16}, {'F',45}};Node* root = buildHuffmanTree(freqMap);unordered_map<char, string> codes;generateCodes(root, "", codes);for (auto& pair : codes) {cout << pair.first << ": " << pair.second << endl;}return 0;
}

5. 应用场景

  • 文件压缩:如 ZIP、GZIP、JPEG、MP3 等格式。
  • 数据传输:减少带宽占用。
  • 数据库存储:压缩文本字段。

6. 优缺点

  • 优点
    • 无损压缩,解压后数据完全恢复。
    • 对高频字符优化,压缩效率高。
  • 缺点
    • 需要存储哈夫曼树或编码表,可能增加额外开销。
    • 不适合字符频率分布均匀的场景。

总结

哈夫曼编码通过构建最优二叉树实现高效压缩,是经典的数据压缩算法之一。理解其核心思想(贪心算法)和实现步骤(构建树、生成编码),是掌握数据压缩技术的基础。


练一练

在这里插入图片描述
答案:B

在这里插入图片描述
答案:A

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/902105.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jetson Orin NX 部署YOLOv12笔记

步骤一.创建虚拟环境 conda create -n yolov12 python3.8.20 注意&#xff1a;YOLOv12/YOLOv11/YOLOv10/YOLOv9/YOLOv8/YOLOv7a/YOLOv5 环境通用 步骤二.激活虚拟环境 conda activate yolov12 #激活环境 步骤三.查询Jetpack出厂版本 Jetson系列平台各型号支持的最高Jetp…

Linux指令篇 (2)

指令篇&#xff08;2&#xff09; Linux基本指令&#xff08;2&#xff09;(1) mkdir指令&#xff08;重要&#xff09;&#xff08;2&#xff09;rmdir指令&&rm指令(重要)&#xff08;3&#xff09;man指令(重要)&#xff08;4&#xff09;cp指令&#xff08;重要&…

致远OA——自定义开发rest接口

文章目录 :apple: 业务流程 &#x1f34e; 业务流程 代码案例&#xff1a; https://pan.quark.cn/s/57fa808c823f 官方文档&#xff1a; https://open.seeyoncloud.com/seeyonapi/781/https://open.seeyoncloud.com/v5devCTP/39/783.html 登录系统 —— 后台管理 —— 切换系…

区块链如何成为智能城市的底层引擎?从数据透明到自动化治理

区块链如何成为智能城市的底层引擎&#xff1f;从数据透明到自动化治理 引言&#xff1a;智能城市真的智能吗&#xff1f; 在数字化时代&#xff0c;智能城市&#xff08;Smart City&#xff09;逐步成为各国推动城市创新的重要方向。城市管理者希望借助物联网&#xff08;IoT…

洛谷P1177【模板】排序:十种排序算法全解(1)

扯谈 之前我已经把十大排序算法全讲了一遍&#xff08;具体详见专栏C排序算法&#xff09;,今天我们来用一道简单的题目总结实战一下。 算法实现 一、桶排序&#xff08;Bucket Sort&#xff09; ‌适用场景‌&#xff1a;数据范围已知且较小&#xff08;需根据测试数据调整…

SuperMap iClient3D for WebGL 如何加载WMTS服务

在 SuperMap iClient3D for WebGL 中加载WMTS服务时&#xff0c;参数配置很关键&#xff01;下面我们详细介绍如何正确填写参数&#xff0c;确保影像服务完美加载。 一、数据制作 对于上述视频中的地图制作&#xff0c;此处不做讲述&#xff0c;如有需要可访问&#xff1a;Onl…

再读bert(Bidirectional Encoder Representations from Transformers)

再读 BERT&#xff0c;仿佛在数字丛林中邂逅一位古老而智慧的先知。初次相见时&#xff0c;惊叹于它以 Transformer 架构为罗盘&#xff0c;在预训练与微调的星河中精准导航&#xff0c;打破 NLP 领域长久以来的迷雾。而如今&#xff0c;书页间跃动的不再仅是 Attention 机制精…

从零开始 保姆级教程 Ubuntu20.04系统安装MySQL8、服务器配置MySQL主从复制、本地navicat远程连接服务器数据库

从零开始&#xff1a;Ubuntu 20.04 系统安装 MySQL 8、服务器配置 MySQL 主从复制、本地 Navicat 远程连接服务器数据库 初始化服务器1. 更新本地软件包列表2. 安装 MySQL 服务器3. 查看 MySQL 安装版本4. 登录 MySQL 管理终端5. 设置 root 用户密码&#xff08;推荐使用 nativ…

java怎么完善注册,如果邮箱中途更换,能否判断

解析在下面 附赠代码 private static class CodeInfo {String code;long timestamp;CodeInfo(String code, long timestamp) {this.code code;this.timestamp timestamp;}}// 存储验证码&#xff08;邮箱 -> 验证码信息&#xff09;(保证线程安全) 以免中途更改邮箱pri…

n8n 中文系列教程_01. 简单易懂的现代AI魔法,n8n的快速了解与概念科普(文末有彩蛋)

1. 教程简介 欢迎来到“无代码工具探索”课程&#xff0c;这是专为非技术人员设计的指南&#xff08;当然&#xff0c;技术人员也可以从中受益&#xff09;。我们的目标是通过无代码工具来提升工作效率&#xff0c;尤其是利用像 n8n 这样的灵活数据库平台。这些工具被誉为“现…

解码 Web Service:从技术原理到应用场景的深度剖析

Web Service 是一种基于网络的、分布式的计算技术&#xff0c;它允许不同的应用程序之间通过网络进行通信和交互。以下是关于 Web Service 的详细介绍&#xff1a; 一、定义与概念 Web Service 是一种可以通过 Web 协议&#xff08;如 HTTP&#xff09;进行访问的软件组件&am…

Nacos启动报错

Nacos启动是在单机模式下&#xff0c;不是集群模式 点击startup.cmd启动会报错 打开bin目录 rem是注释的意思&#xff0c;在nacos1.3.2之后&#xff0c;nacos默认的都是集群模式&#xff0c;我们这里单机测试就是用单机模式。 也可以修改MODE&#xff0c;如果选择不修改&…

uniapp-商城-26-vuex 使用流程

为了能在所有的页面都实现状态管理&#xff0c;我们按照前面讲的页面进行状态获取&#xff0c;然后再进行页面设置和布局&#xff0c;那就是重复工作&#xff0c;vuex 就会解决这样的问题&#xff0c;如同类、高度提炼的接口来帮助我们实现这些重复工作的管理。避免一直在造一样…

Git 命令速查手册

听说用美图可以钓读者&#xff1f; 一、基础操作核心命令 1. 仓库初始化与克隆 命令作用示例git init创建新仓库git init my-projectgit clone克隆远程仓库git clone [https://github.com/user/repo.git](https://github.com/user/repo.git)git remote add关联远程仓库git re…

信息量、香农熵、交叉熵、KL散度总结

信息量 对于一个事件而言&#xff0c;它一般具有三个特征&#xff1a; 小概率事件往往具有较大的信息量 大概率事件往往具有较小的信息量 独立事件的信息量相互可以相加 比如我们在买彩票这个事件中&#xff0c;彩票未中奖的概率往往很高&#xff0c;对我们而言一点也不稀…

使用C语言的cJSON中给JSON字符串添加转义

在 cJSON 库中&#xff0c;没有直接提供 一个函数来专门给 JSON 字符串添加转义&#xff08;如将 " 转义为 \"&#xff0c;\n 转义为 \\n 等&#xff09;。 但 cJSON 在 序列化&#xff08;cJSON_Print 或 cJSON_PrintUnformatted&#xff09; 时会自动处理转义字符…

宇树机器狗go2—slam建图(1)点云格式

0.前言 上一篇番外文章教大家如何在宇树机器狗go2的gazebo仿真环境中实现简单的导航运动&#xff0c;本期文章会教大家如何让宇树的机器狗go2在仿真环境中进行slam建图时经常会遇到的一些点云格式&#xff0c;在后续的slam建图和slam算法解析的时候会经常与这些点云信息打交道…

linux socket编程之udp(实现客户端和服务端消息的发送和接收)

目录 一.创建socket套接字(服务器端) 二.bind将prot与端口号进行绑定(服务器端) 2.1填充sockaddr_in结构 2.2bind绑定端口 三.直接通信(服务器端) 3.1接收客户端发送的消息 3.2给客户端发送消息 四.客户端通信 4.1创建socket套接字 4.2客户端bind问题 4.3直接通信即可…

第1期:Python基础语法入门

1.1 Python简介 Python是一种解释型、面向对象、动态数据类型的高级编程语言。它设计简洁&#xff0c;易于学习&#xff0c;适合初学者。Python广泛应用于数据科学、人工智能、Web开发、自动化脚本等领域。它的语法简洁易懂&#xff0c;强调代码的可读性。 1.2 安装Python与配…

使用EXCEL绘制平滑曲线

播主播主&#xff0c;你都多少天没更新了&#xff01;&#xff01;&#xff01;泥在干什么&#xff1f;你还做这个账号麻&#xff1f;&#xff01;&#xff01;&#xff01; 做的做的&#xff08;哭唧唧&#xff09;&#xff0c;就是最近有些忙&#xff0c;以及…… 前言&…