实验3-huffman编解码

一、实验原理
哈夫曼编码(Huffman Coding),又称霍夫曼编码或最佳码,是可变字长编码(VLC)的一种,属于无损压缩。该方法完全依据字符出现概率来构造码字,出现概率大的符号码长短,概率小的码长大,能有效的减小码长,对于概率分布相差大的信源压缩效率高,而对于接近于等概分布的信源压缩效率低。
实际实现中常用二叉树来表示编码过程,节点需要表示的信息有它的概率;它是否为叶子节点,不是则表示是一个中间节点,它有左右子节点,是叶子结点则有一个符号;它的父节点用于建立码树。 由于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;

每个码字的数据结构为:

typedef struct huffman_code_tag
{
    //add by zhn
    int count;//出现频率
    //end add
    /* The length of this code in bits. */
    unsigned long numbits;//比特位数
    unsigned char *bits;//比特流
} huffman_code;

它的编码步骤为
1)统计个符号出现的次数,按照它们出现的概率并从大到小依次排列。
2)每次取概率最小的两个节点,合并概率,生成父节点,用父节点代替这两个子节点重新排序,直到根结点。
3)分配码字,二叉树的左节点为0,右节点为1,从根到叶子结点遍历得到码字。
二、实验步骤
1.huffman编码流程
这里写图片描述
1)读入文件

    char memory = 0; //memory为1表示对内存编码
    char compress = 1;//compress为1表示压缩,为0是解压
    int opt;
    //add by zhn
    const char *file_in = NULL, *file_out = NULL;
    const char *file_table=NULL;
    FILE *in = stdin;//标准输入
    FILE *out = stdout;//标准输出
    //add by zhn
    FILE *table;//输出码表
    while((opt = getopt(argc, argv, "i:o:t:cdhvm")) != -1)//对argc,argv的解析,单个字符后跟一个冒号表示后面必须接参数
    {
        switch(opt)
        {
        case 'i':
            file_in = optarg;
            break;
        case 'o':
            file_out = optarg;
            break;
        //add by zhn
        case 't':
            file_table = 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;
            break;
        default:
            usage(stderr);
            return 1;
        }
    }

2)统计各个字符出现的概率

#define MAX_SYMBOLS 256//共有256个字符
typedef huffman_node* SymbolFrequencies[MAX_SYMBOLS];
typedef huffman_code* SymbolEncoder[MAX_SYMBOLS];
static void
init_frequencies(S
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
信源编 Assignment of CH1 1、 什么是数据压缩,一般分为几类?请列举实例说明。 数据压缩,就是以最少的数表示信源所发出的信号,减少容纳给定信息集合或数据采样集合的信号空间。 其主要分为两大类型:lossless 和 lossy。其具体分类和实例用图表表示如下: 数据压缩 冗余度压缩(熵编) lossless 统计编 霍夫曼编、游程编、二进制信源编等 算术编 基于字典的编、LZW 编等 其他编 完全可逆的小波分解+统计编等 熵压缩 (lossy) 特征抽取 分析/综合编 子带、小波、分类、模型基等 量化 其他 无记忆量化编 均匀量化、Max 量化、压扩量化等 有 记忆量化 序列量化 预测编 增量调制、线性预测、非线性预测、自适应预测、运动补偿预测等 其他方法 序贯量化等 分组量化 直接映射 矢量量化、神经网络、方块截尾等 变化编 正交变换:KLT、DCT、DFT、WHT 等 非正交变换 其他函数变换等 2、 什么是信源编,他与数据压缩有何关系? 信源编是一种以提高通信有效性为目的而对信源符号进行的变换,或者说为了减少或消除信源冗余度而进行的信源符号变换。 信源编的作用有二 : 一是实现模拟信号的数字化传输;二就是设法减少元数目和降低元速率,即所谓的数据压缩技术。信源编理论和数据压缩理论之间没有明显差别。
Huffman编解码是一种用于数据压缩和解压缩的算法。其原理基于字符出现的频率来构建一棵Huffman树,并通过不同的编方式来表示每个字符,以实现最优的压缩效果。 Huffman过程首先统计所有字符出现的频率,并将其作为树节点的权值。然后,根据频率构建一个森林,森林中每个节点都是一个树。接下来,取出森林中权值最小的两棵树,将它们合并为一棵树。并将合并后的树插入森林中。重复此过程,直到森林中只剩下一棵树,即Huffman树。 Huffman树的构建采用贪心算法,即每次选择频率最小的两个节点进行组合。合并生成的新节点的权值为这两个节点的权值之和,并将其作为树的根节点。左子树编为0,右子树编为1。通过不断合并和编操作,生成了一颗Huffman树。 编过程中,根据Huffman树的路径从根节点到叶子节点的编规则,对每个字符进行编。由于Huffman树的构建过程中,频率高的字符位于树的顶部,而频率低的字符位于树的底部,所以频率高的字符编较短,频率低的字符编较长,从而实现了数据的压缩效果。 解过程中,根据Huffman树的编规则,从根节点开始,依次读取编位,并根据位的值来选择左子树或右子树,直到达到叶子节点,找到对应的字符。 通过Huffman编解码原理,可以有效地对数据进行压缩和解压缩,提高数据传输和存储的效率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值