【数据压缩】Huffman编解码器

Huffman编码之文件的解/压缩 史上最具人性化的文件压缩详述,基于Huffman算法的文件压缩项目,还在为找练习项目而苦恼?还在为Huffman算法困惑?还在为文件压缩一头雾水?来吧,,,一起学习,共同进步..... 阅读详情

一.实验原理

1.Huffman编码

1)Huffman Coding(霍夫曼编码)是一种无失真编码的编码方式,Huffman编码是可编长编码(VLC)的一种。
2)Huffman编码基于信源的概率统计模型,它的基本思路是:出现概率大的信源符号编短码,出现概率小的编长码。从而实现平均码长最小。
3)在程序实现中常使用一种叫做树的数据结构实现Huffman编码,由它编出的码是即时码。

2.Huffman编码的方法

2.1 统计符号的发生概率;
2.2 把频率从小到大的顺序排列
2.3 每一次选出最小的两个值,作为二叉树的两个叶子节点,将和作为它们的根节点,这两个叶子节点不再参与比较,新的根节点参与比较;
2.4 重复3,知道最后得到和为1的根节点。
2.5 将形成的二叉树的左节点标为0,右节点标为1,把从最上面的根节点到最下面的叶子节点途中遇到的0,1序列串起来,就得到了各个符号的编码。

3.实验中遇到的递归式遍历方法

  • 先序遍历
    先序遍历

  • 中序遍历
    中序变绿

  • 后序遍历
    后序遍历

    综上,Huffman编码结构中, build_symbol_encoder()的函数,实现功能为:对存在的每个字符计算码字。该函数使用的遍历方法应该为递归”中序遍历”;假设已经遍历到最左边的叶节点,由if判断到叶节点的子节点为空,故Return。此时输出一个码子,然后进入下一个右节点。其对节点的遍历顺序应为,中序遍历。仅单纯观察代码易混淆为先序遍历。

     if(subtree == NULL)
        return;
    
    if(subtree->isLeaf)
        (*pSF)[subtree->symbol] = new_code(subtree);
    else
    {
        
        //如果不是叶字节点,就需要往下遍历
        build_symbol_encoder(subtree->zero, pSF);//先遍历其左子树
        build_symbol_encoder(subtree->one, pSF);//再遍历其右子树
    }

4.实验中所用到的数据结构分析

 typedef struct huffman_node_tag
{
    unsigned char isLeaf;//判断该节点是否是叶节点的标志
    unsigned long count;//信源中出现频数
    struct huffman_node_tag *parent;//父节点指针

    union
    {
        struct
        {
            struct huffman_node_tag *zero, *one;
        };
        unsigned char symbol;
    };
} huffman_node;

huffman_node节点中的有union数据结构,这么设计的优点是节约了空间。当节点为叶节点时,必定不包含子节点指针,当节点非叶节点时,必存在子节点指针。

typedef struct huffman_code_tag
{
    /* The length of this code in bits. */
    unsigned long numbits;

    /* The bits that make up this code. The first
       bit is at position 0 in bits[0]. The second
       bit is at position 1 in bits[0]. The eighth
       bit is at position 7 in bits[0]. The ninth
       bit is at position 0 in bits[1]. */
    unsigned char *bits;
} huffman_code;

huffman_code是Huffman码表数据结构,用以储存符号对应的码字。

    typedef struct huffman_info_tag
{
    double freq;//符号出现频率
    unsigned long len_code;//符号对应的码长
    unsigned char *code;//符号对应的码字
}huffman_info;

huffman_info数据结构,用于储存每个符号的符号频率、码长、码字信息。用于压缩后统计压缩数据,计算压缩效率,以及验证压缩正确性。

  • 分别定义三个数组,数组中储存的是指向结构体的指针。
 #define MAX_SYMBOLS 256
typedef huffman_node* SymbolFrequencies[MAX_SYMBOLS];
typedef huffman_code* SymbolEncoder[MAX_SYMBOLS];
//cai add 
typedef huffman_info* SymbolInfo[MAX_SYMBOLS];

举例,SymbolFrequencies[MAX_SYMBOLS]储存着256个指向huffman_node这个结构体的指针。

5.getopt()函数简单分析

传入的参数,例如:"-i input.rgb -o output.rgb -c"  "i"与“o”在下列注释中称为key,其对应的“input.rgb”称为value。
以及调用getopt时,opt = getopt(argc, argv, "i:o:cdhvm")。"i:o:cdhvm"在下列注释中称为规范字符串
extern char *optarg;
extern int optind;
extern int opterr;

int opterr = 1,     /* if error message should be printed */
    optind = 1,     /* index into parent argv vector */
    optopt,         /* character checked for validity */
    optreset;       /* reset getopt */
char    *optarg;        /* argument associated with option */

#define BADCH   (int)'?'
#define BADARG  (int)':'
#define EMSG    ""
int getopt(int nargc, char * const *nargv, const char* ostr)
{
    static char *place = EMSG;      /* place向量先置为空 */
    char *oli;              /* 用于指向 “规范字符串”的指针 */

    if (optreset || !*place) {      /* 如果optreset为1,或者place指向空,都会进入这个判断 */
        optreset = 0;               /*进入后,将optreset重置为0*/
        if (optind >= nargc || *(place = nargv[optind]) != '-') {       /*判断optind是否比总argc数大,以及argv[opind]的第一个字符是否为'-' .*/
            place = EMSG;                                               /*若满足其上任一项,说明字符读取到了最后一步,或者输入有误*/
            return (EOF);                                               /*将place指向 argv[optind]*/
        }
        if (place[1] && *++place == '-') {  /* found "--" */            /*如果place的后一位仍指向某个字符,且该字符也
Huffman编码解压缩的通俗讲解 前言好久没写博客了,主要是各种事缠着,难以抽出时间。这两个月以来,由于项目需要,我也逼着自己学到了很多,什么java后台,web前端,还有万恶的OpenCV图形处理……,呵呵,全栈:( 。但对Android的学习我始终不肯放下。但是今天这篇博客不是关于Android的,而是算法的相关应用–哈夫曼压缩。这是数据结构与算法实验里面的一个项目,网上关于这方面的资料很多,但大多数博客都是随便讲讲然后扔下代码 阅读详情

相关推荐

【数据压缩】实验:DPCM压缩系统的实现与分析

预测编码指根据某一模型利用旧的样本值对新样本值进行预测,然后将样本的实际值与其预测值相减得到误差值,对于这一误差值进行编码。如果模型足够好且样本序列在时间上相关性较强,那么误差信号的幅度将远远小于原始信号,从而得到较大的数据压缩结果。预测编码方法分线性预测和非线性预测编码方法。线性预测编码方法也称差值脉冲编码调制法,简称DPCM。DPCM编解码过程如下图:编码器(Encoder)中Q是量化器,P是预测器。输入信号Xn是某一像素点的实际灰度值,Pn是对该像素点的预测值,dn 是预测误差,^(dn)是量化预测误

weixin_48946798的博客 586

数据压缩核心技术解析:从预测编码到熵编码的完整流程与实践

数据压缩是计算机科学中提升存储与传输效率的基础技术,其核心原理在于识别并消除数据中的冗余信息。通过预测编码技术,系统可以利用数据间的相关性,将原始序列转换为更紧凑的残差序列。随后,熵编码技术(如霍夫曼编码)根据符号出现概率分配不同长度的码字,实现高效的无损压缩。这一技术组合在数据库列式存储和大数据系统中具有极高价值,能显著节省存储空间并加速查询分析。本文以模拟的“Pi”压缩机制为例,通过Python代码完整演示了从差分预测、ZigZag整数映射到霍夫曼编码的工程实现流程,为理解通用压缩框架提供了清晰的实践路

weixin_34268753的博客 317

MFC下的哈夫曼编码及应用

这是本人根据数据结构做的一个哈夫曼树的应用程序,用MFC实现,主要有如下功能:1.输入一段文字并实现编码。2.将编码的文字进行译码。3.统计输入字符的权值并给出编码。4.画出哈夫曼树。5.能通过网络发送并接受数据(PS:这个功能本意是要接受对方的二进制码并进行翻译,但本人能力有限,没能解决这个问题,希望有能力的朋友解决后能给我留言,谢谢!)这个程序本人做了一周,实属不易,所以分高了点,但是物有所值^_^

Huffman编码对英文文本的压缩和解压缩

Huffman编码对英文文本的压缩和解压缩

(c++)自适应哈夫曼编码

自己写的自适应哈夫曼编码,备份用。有需要的拿,也可以从文章里复制。

Adaptive-Huffman:自适应霍夫曼编码的Java实现

自适应霍夫曼 使用Vitter算法在Java中实现自适应霍夫曼编码。 如何运行编码器 使用javac进行编译 $ java adaptiveHuffman.encoder.Encoder InputFile OutputFile` 其中InputFile是要压缩的一些文本或其他文件,而OutputFile是将压缩后的代码写入的位置。 如何运行解码器 $ java adaptiveHuffman.decoder.Decoder InputFile OutputFile 其中InputFile是压缩的中间文件,而OutputFile是将未压缩的数据写入的位置。

从数据校准到论文呈现:fsQCA与NCA方法融合的完整实证研究指南

本文详细介绍了fsQCA(模糊集定性比较分析)与NCA(必要条件分析)方法融合的完整实证研究流程,从数据校准到论文呈现。通过软件操作技巧、R语言NCA包高效使用及论文写作规范,帮助研究者避免常见误区,提升研究质量与可靠性。特别适合需要进行组态分析的研究生和学者参考。

weixin_29215391的博客 414

用PLECS搞定三相逆变器电流环:从传递函数推导到PI参数整定的保姆级教程

本文提供了一份详细的PLECS教程,指导如何从传递函数推导到PI参数整定,实现三相逆变器电流环的闭环控制。通过坐标变换、控制器设计和仿真验证等步骤,帮助工程师快速掌握电流环控制技术,提升电力电子系统的稳定性和可靠性。

weixin_27102543的博客 399

Wazuh部署记录

Wazuh是一个免费的开源安全平台,统一了XDR和SIEM功能。它可以保护内部部署、虚拟化、容器化和基于云的环境中的工作负载。Wazuh帮助组织和个人保护其数据资产免受安全威胁。它被全球数千个组织广泛使用,从小型企业到大型企业。443:仪表盘界面访问端口1515:探针连接服务器端口1514:探针回传信息端口以上3个端口必须打开防火墙。

墨痕诉清风的博客 1561

YOLOv11改进策略【Neck】| PRCV 2023,SBA(Selective Boundary Aggregation):特征融合模块,描绘物体轮廓重新校准物体位置,解决边界模糊问题

SBA 模块在医疗图像分割中具有重要作用,其设计出发点是解决图像中物体边界模糊以及融合特征时的冗余和不一致问题。

Limiiiing的博客 1943

使用 Visual Studio Code 连接 ABAP On-Premise 系统做开发的详细配置步骤

本文详细介绍了如何在Visual Studio Code中通过ABAP Development Tools扩展连接ABAP On-Premise系统。关键步骤包括:通过Ctrl+Shift+P打开命令行面板选择「ABAP: New Destination...」创建RFC连接(仅支持SSO单点登录),选择本地SAPGUI中已有的系统,输入Client ID、语言和用户名(无需密码),最后将目标系统添加到工作区即可开始开发。文章强调了企业安全考虑下仅支持SSO的设计理念,并展示了连接配置的JSON格式示例。整

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 987

7、Python高光谱分析工具(PyHAT)简介

Python高光谱分析工具(PyHAT)是一个开源、跨平台的Python库及图形用户界面,用于行星光谱数据的可视化与分析。它支持多种高光谱传感器数据,如火星勘测轨道飞行器的CRISM、月船1号的M3以及SELENE Kaguya SP点光谱仪,提供预处理、衍生产品生成、统计学习和机器学习分析功能。PyHAT基于Pandas和NumPy构建,兼容Jupyter和QGIS环境,旨在解决现有光谱分析方法缺乏开源实现、难以探索性分析和算法分散的问题。其模块化架构涵盖数据输入/输出、通用光谱变换、测绘与点观测工具及高

aa123的博客 138

【数字IC刷题】华为海思数字IC笔试题(1)详细解析版

【数字IC刷题】华为海思数字IC笔试题(1)详细解析版

MoorePlus的博客 4221

一文读懂 STAR-CCM+:多物理场仿真王者,从入门到精通全攻略(附实战路线)

STAR-CCM+是西门子旗下的多物理场仿真平台,集流体、传热、结构、电磁等耦合求解于一体。其核心优势包括:全自动网格处理技术(支持十亿级网格)、多物理场无缝耦合、CPU/GPU并行加速计算、流程自动化与设计探索等。广泛应用于汽车(空气动力学优化、电池热管理)、航空航天(气动设计、发动机仿真)、能源(风电叶片流固耦合)、电子(芯片散热)等行业。相比ANSYS Fluent和OpenFOAM,STAR-CCM+在多物理场耦合和复杂几何处理方面更具优势,适合工业级高精度仿真需求。学习路径建议从基础操作入手,逐步

源代码杀手的博客 340

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: 【数据压缩】wav格式初学习
下一篇: 【数据压缩】DPCM 压缩系统的实现和分析
caidejun
博客等级 码龄10年 10粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值