Huffman编码的C语言实现

实验原理

Huffman 编码

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

Huffman编码的数据结构
typedef struct huffman_node_tag
{
    unsigned char isLeaf;//是否为树叶
    unsigned long count;//节点代表的符号加权和
    struct huffman_node_tag *parent;//父节点指针

    union//共同体:如果是叶节点,则只能有symbol,如果是非叶节点,只能有左右孩子指针
    {
        struct
        {
            struct huffman_node_tag *zero, *one;//左右孩子指针
        };
        unsigned char symbol;//符号,叶节点带有的字符
    };
} huffman_node;
typedef struct huffman_code_tag
{
    /*以比特为单位的代码的长度。 */
    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 编码的方法

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

实验流程

这里写图片描述

重要代码分析

读入待编码的源文件

int
main(int argc, char** argv)//argc命令行参数个数和argv命令行参数
{
    char memory = 0;//memory为0时,为文件的编解码,memory为1时为内存的编解码
    char compress = 1;//compress为1时为编码,为0时为解码
    int opt;//getopt()的返回值 
    const char *file_in = NULL, *file_out = NULL;//输入输出文件名
    //step1:add by yzhang for huffman statistics
    const char *file_out_table = NULL;
    //end by yzhang
    FILE *in = stdin;
    FILE *out = stdout;
    //step1:add by yzhang for huffman statistics
    FILE * outTable = NULL;//用于txt文件的输出
    //end by yzhang

    /* 获取命令行参数 */
    while((opt = getopt(argc, argv, "i:o:cdhvm")) != -1)//opt的返回值为iocdhvm或-1,getopt处理以'-’开头的命令行参数
    {
        switch(opt)
        {
        case 'i'://输入文件
            file_in = optarg;//optarg为选项参数缩写,该变量存放参数
            break;
        case 'o'://输出文件
            file_out = optarg;
            break;
        case 'c'://压缩
            compress = 1;
            break;
        case 'd'://解压缩
            compress = 0;
            break;
        case 'h'://帮助显示使用方法
            usage(stdout);
            return 0;
        case 'v'://输出版本版权信息
            version(stdout);
            return 0;
        case 'm':
            memory = 1; //memory为1时为内存的编解码
            break;
        // by yzhang for huffman statistics
        case 't':
            file_out_table = optarg;            
            break;
        //end by yzhang
        default:
            usage(stderr); //如果是其他情况,则将使用方法信息送到标准错误文件
            return 1;
        }
    }

getopt()函数是Linux和Unix系统环境下解析命令行的函数。在本次实验中,命令行可设置为“-i test1.doc -o test1.huff -c -t test1.txt”

Huffman文件编码时的总流程

#define MAX_SYMBOLS 256
typedef huffman_node* SymbolFrequencies[MAX_SYMBOLS];//表示信源符号的数组
typedef huffman_code* SymbolEncoder[MAX_SYMBOLS];//表示码字的数组,用于保存码表

Huffman文

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值