数据压缩原理与应用 Huffman编码

一.Huffman编码的原理

Huffman Coding (霍夫曼编码)是一种无失真编码的编码方式,Huffman 编码是可变字长编码(VLC)的一种。
Huffman 编码基于信源的概率统计模型,它的基本思路是出现概率大的信源符号编长码,出现概率小的信源符号编短码,从而使平均码长最小。
在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。
在程序实现中常使用一种叫做树的数据结构实现 Huffman 编码,由它编出的码是即时码。

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

举例:
这里写图片描述

  • huffman节点
     /*huffman二叉树*/
    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编码
    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]. */
           /* 码字, 码字的第 1 位存于 bits[0]的第 1 位,
           码字的第 2 位存于 bits[0]的第的第 2 位,
           码字的第 8 位存于 bits[0]的第的第 8 位,
           码字的第 9 位存于 bits[1]的第的第 1 位 */
        unsigned char *bits;
    } huffman_code;
  • huffman表格
     /*对输出的表格进行结构化 针对huff_run main函数 */
    //输出的表格有些变量可以直接写进结构体里,如此表格可以很快输出,再加入新变量也不会很复杂
    typedef struct huffman_statistics_result
    {
        float freq[256];
        unsigned long numbits[256];
        unsigned char bits[256][100];
    }huffman_stat;

二.实验流程

这里写图片描述


三.代码分析

1.读取待编码的文件

首先对命令行的参数进行定义

    static void
    usage(FILE* out)//命令行参数的设置
    {
        fputs("Usage: huffcode [-i<input file>] [-o<output file>] [-d|-c]\n"
              "-i - input file (default is standard input)\n"//输入文件
              "-o - output file (default is standard output)\n"//输出文件
              "-d - decompress\n"//解压缩操作
              "-c - compress (default)\n"//压缩操作
              "-m - read file into memory, compress, then write to file (not default)\n",//读内存
              "-t - output huffman statistics\n",//输出huffman统计表格
              out);
    }

主函数,对命令行参数进行设计

    int
    main(int argc, char** argv)//命令行参数
    {
        char memory = 0;//内存操作的标识符
        char compress = 1;//解压缩的标识符
        int opt;//命令行参数选项
        const char *file_in = NULL, *file_out = NULL;
        const char *file_out_table = NULL;
        FILE *in = stdin;
        FILE *out = stdout;
        FILE * outTable = NULL;

            /* Get the command line arguments. */
        while((opt = getopt(argc, argv, "i:o:cdhvmt:")) != -1) //读取命令行参数的选项
        {
            switch(opt)
            {
            case 'i':
                file_in = optarg;//选择i,输入文件
                break;
            case 'o':
                file_out = optarg;//选择o,输出文件
                break;
            case 'c':
                compress = 1;//选择c,压缩
                break;
            case 'd':
                compress = 0;//选择d,解压缩
                break;
        
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值