赫夫曼编/译码系统

 

赫夫曼编码/译码器

摘要:

   利用赫夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。这要求在 发送端通过一个编码系统对待传输数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要有一个完整的编/译码系统。本文编写了一个简单的赫夫曼码的编/译码小程序。

    本程序主要实现了利用赫夫曼二叉树对一篇英语文档进行编码,对得到的编码利用同一个二叉树解码,最后对解码得到的文档进行测试。经过测试后得出结论,赫夫曼编码虽然提高了信道的利用率,但在信号的保真度上不高,一旦信号出错,整个译码将出错。

实验目的:

   理解Huffman二叉树的概念

   学会使用Huffman编码对数据进行无损压缩的原理

 

 

一、问题描述: 

     利用赫夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。这要求在 发送端通过一个编码系统对待传输数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要有一个完整的编/译码系统。本文编写了一个简单的赫夫曼码的编/译码小程序。

二、设计要求:

   该程序有以下流程:

Initialization(初始化):从输入端输入标准字符集(initdata.dat)和待编码ASCII文件(data.dat),并统计和计算出文章中出现的字符频率,概率和字符数。并计算出信源熵H(entropy)。

EnCoding(编码过程):由输入端输入的各字符出现频率为权值构造赫夫曼二叉树。子叶便是文中出现的各字符。通过根到子叶的路径将其转换为赫夫曼编码。再将源文档中的字符替换为相应的赫夫曼码,并存档(code.dat)。

DeCoding(译码过程):在接收端接收到译码文件(code.dat)后,利用译码过程中生成的赫夫曼二叉树译码。对译码文件扫描,将赫夫曼码替换为原文档,结果存为文档(test.dat)。

Testing(测试):对原文件和译码文件进行校队,相同则编译成功,不相同则编译失败。

Print(打印代码文件):打印内存中的赫夫曼树。各字符对应的编码,编码平均长度,编码效率(信源熵/编码平均长度),显示原文本,编码文本和译码文本。

三、算法描述:

 编码算法:

Input:w[],n//权值数组和数组的大小

Output:HT,HC//赫夫曼二叉树和赫夫曼编码表。

1.由输入的权值数组构造n个赋权的二叉树。

2.在这些二叉树中选取权值最小的两个构造一棵新的二叉树,并删除子叶。

3.如果只剩一棵二叉树,则赫夫曼二叉树构造完毕。否则在剩下的二叉树中返回第二步。

//---从子叶到个逆向求每个字符的赫夫曼编码------

1.从上面过程构造出的二叉树的第一个子叶开始,寻找它的双亲。

2.判断当前结点有无双亲,若无双亲,则全部出栈,并存入赫夫曼编码表吗,下一个子叶结点,转第一步。

3.判断当前结点是其双亲的左孩子还是右孩子,左孩子,则‘0’入栈,右孩子,则‘1’入栈。

   

 

 

 

译码算法:

   Input:code.dat

   Output:test.dat

从code文件的开始到结尾依次读取字符,通过读取到的字符从赫夫曼二叉树的根结点开始,‘0’当前结点换为左孩子,‘1’当前结点换为右孩子,

重复上述过程直到叶子结点,并输出叶子节点所代表的字符到test文件中。

 

 

测试算法:

 Intput;test.dat,data.dat//译码文件和原文件

  Output:true or false

  分别比较两个文件中的字符是否一样,只有全部一样才返回true否则返回false

 

 

四、变量说明:

    #define MAX_CHARS_NUM 57

    #define MAX_ROW 100

    #define MAX_COL 100

   char chars[MAX_CHARS_NUM];//存储标准字符集

   char article[MAX_ROW][MAX_COL];//存储待统计文章

   int frequence[MAX_CHARS_NUM] = {0};//各字符出现的频度

   int size = 0; //文章中出现过的字符数目

   vector<char> appCh;//出现过的字符

   vector<int> appFre;//出现过的字符的频率

   vector<double> probty;//出现过的字符的概率

   double entropy;//信源熵

//=====本变量说明包含在"Initialization.h"中=======

   typedef struct 

{

unsigned int weight;//权值

char         info; //子叶所代表的字符信息

unsigned int parent, lchild, rchild;

}HTNode, *HuffmanTree; // 数组存储的Huffam树

typedef char **HuffmanCode; // 编码表

 

 

 

 

五、函数说明:

  #include "Initialization.h"

过程一:

void initChars(ifstream &);

初始化标准字符集,从文件初始化

void initArt(ifstream &);

初始化文章

void statistic(char (*)[MAX_COL], char *);

统计字符频率

void fillApp(char *, int *);

初始化非零频率字符集

void calcuPro(vector<int> &, vector<double> &);

计算字符概率,信源概率

void calcuEnt(vector<double> &,double &);

计算信源熵

   利用公式-∑p(xi)log2(p(xi))

void readAndFill();

第一个过程的封装函数

 

#include "EnCoding.h"

第二个过程--编码阶段

int min1(HuffmanTree ,int );

取最小值,辅助Select函数

void Select(HuffmanTree &,int ,int &,int &);

选取最小和次小值

void HuffmanCoding(HuffmanTree &, HuffmanCode &,vector<int> &, int );

编码函数

void documentCode(vector<string> &);

创建"code.dat"文件

 

#include "DeCoding.h"

第三个阶段--译码阶段

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值