哈夫曼(Huffman)编码

一、实验目的
1、掌握二叉树基本概念。
2、掌握二叉树建立方法。
3、掌握二叉树基本操作和遍历方法。
4、掌握哈夫曼(Huffman)树建立、编码
5、了解解码方法。

二、实验内容
1、二叉树的定义和操作。
2、对输入权值个数及其权值,构造哈夫曼树。
         权值数量 5
         权值 5 4 3 2 1
3、输出其哈夫曼编码。

三、根据课本内容,编写以下程序
1、请编程实现二叉树的二叉链表链式存储。
2、请编程实现二叉树的前序,后序和中序遍历。
3、请编程实现哈夫曼树和哈夫曼树编码

【例如】

输入:
6
1 3 5 7 4 9

输出:
1010 1011 00 01 100 11


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
    int weight;
    int parent,lch,rch;
}HTNode, *HuffmanTree;
typedef char *HuffmanCode;


void Select(HuffmanTree *HT, int n, int *s1, int *s2)
{
    int a, b, i;
    int min = 1024;
    for(i = 1; i <= n; i++) {
        if((*HT)[i].parent == 0  && (*HT)[i].weight < min ){
            min = (*HT)[i].weight;
            a = i;
        }
    }
    *s1 = a;
 
    min = 1024;
    for(i = 1; i <= n; i++) {
        if((*HT)[i].parent == 0  && (*HT)[i].weight < min && i != a){
            min = (*HT)[i].weight;
            b = i;
        }
    }
    *s2 = b;
}

void CreatHuffmanTree(HuffmanTree *HT, int n)
{
    int i, s1, s2;
    if(n <= 1)
        return;
    int m = 2 * n - 1;
    *HT = (HuffmanTree)malloc((m+1)*sizeof(HTNode));
    for(i = 1; i <= m; i++){
        (*HT)[i].lch = 0;
        (*HT)[i].rch = 0;
        (*HT)[i].parent = 0;
    }
    for(i = 1; i <= n; i++)
        scanf("%d", &(*HT)[i].weight);
 
    for(i = n + 1; i <= m; i++){
        Select(HT, i-1, &s1, &s2);
        (*HT)[s1].parent = i;
        (*HT)[s2].parent = i;
        (*HT)[i].lch = s1;
        (*HT)[i].rch = s2;
        (*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight;
    }
}

void CreatHuffmanCode(HuffmanTree *HT, HuffmanCode *HC, int n)
{
    char *cd;
    int i;
    HC = (char **)malloc((n+1)*sizeof(char *));
    cd = (char *)malloc(n*sizeof(char));
    cd[n-1] = '\0';
    for(i = 1; i <= n; i++){
        int start = n - 1;
        int c = i;
        int f = (*HT)[i].parent;
        while(f){
            --start;
            if((*HT)[f].lch == c)
                cd[start] = '0';
            else
                cd[start] = '1';
            c = f;
            f = (*HT)[f].parent;
        }
        HC[i] = (char *)malloc((n-start)*sizeof(char));
        strcpy(HC[i], &cd[start]);
    }
    for(i = 1; i <= n; i++)
        printf("%s ",HC[i]);
    printf("\n");
    free(cd);
}

int main()
{
    int n;
    HuffmanTree ht;
    HuffmanCode hc;
    scanf("%d", &n);
    CreatHuffmanTree(&ht, n);
    CreatHuffmanCode(&ht, &hc, n);
    return 0;
}
### Matlab 实现图像的哈夫曼 (Huffman) 编码和解码 #### 1. 统计字符频率 为了实现霍夫曼编码,首先需要计算输入图像中各个灰度级出现的概率分布。这一步骤对于后续构建霍夫曼树至关重要。 ```matlab % 计算每个像素值的频数 pixelCounts = histcounts(imageData(:), 0:255); totalPixels = numel(imageData); % 转换为概率 probabilities = pixelCounts / totalPixels; ``` 此代码片段展示了如何统计给定图像 `imageData` 中各像素值的频率并转换成相应的概率[^1]。 #### 2. 构建霍夫曼树 根据上述得到的概率分布,接下来要创建一棵最小带权路径长度之和最短的二叉树——即霍夫曼树。该树用于生成针对不同符号的最佳前缀码表。 ```matlab huffTree = huffmandict(1:256, probabilities'); ``` 这里调用了内置函数 `huffmandict()` 来自动完成霍夫曼树及其对应编码字典的建立工作[^2]。 #### 3. 对原始数据进行编码 有了前面准备好的霍夫曼编码映射关系之后,就可以按照这个规则把原图中的每一个像素替换成更紧凑的形式表示出来: ```matlab encodedImage = huffmanenco(double(imageData(:)), huffTree); ``` 这段程序会遍历整个图片矩阵,并依据之前定义好的霍夫曼编码方案逐个替换掉原来的数值[^3]。 #### 4. 存储压缩后的位流 经过霍夫曼编码处理过的比特序列通常会被保存下来以便传输或存储,在实际应用当中可能还需要加上一些额外的信息比如宽度高度等参数方便以后还原图像尺寸大小。 #### 5. 进行解码操作 当接收到被压缩过的内容时,则需反向解析回原来的样子。首先是读取出附加信息确定好画布规格;接着再利用相同的霍夫曼译码器将紧缩版的数据串重新展开成为完整的二维数组形式。 ```matlab decodedVector = huffmandeco(encodedImage, huffTree); reconstructedImage = reshape(uint8(decodedVector), size(imageData)); ``` 最后通过重塑命令让一维矢量恢复到初始的空间布局结构之中去形成最终重现出来的影像副本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

要告别理想怎算活過

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值