实验3-huffman编解码

本文介绍了哈夫曼编码的原理,这是一种无损压缩方法,根据字符出现概率构造码字。通过建立二叉树来表示编码过程,详细阐述了编码和解码的步骤,并展示了实验结果及不同文件格式的编码效果。哈夫曼编码对于概率分布不均匀的信源压缩效果显著,但对于等概率分布的信源效果不佳。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、实验原理
哈夫曼编码(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(SymbolFrequencies *pSF)
{
    memset(*pSF, 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值