哈夫曼编码实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
赫夫曼编码实验报告
一、实验内容
实现赫夫曼编码的算法
二、哈夫曼编码的实验步骤
1.输入n个信源符号及其对应的权值
2.利用select()函数找出权值最小的两个信源,并各自分配一个码元“0”“1”,并将这两个信源合并为一个新的信源,其权
值为这两个最小信源的权值之和,得到一个包n-1个信源符号
的新信源,这一过程叫做信源的第一次缩减
3.重复步骤二,直到只剩下两个符号为止,此时从最后一级缩减
信源开始,依编码路经向前返回,得到各信源符号所对应的码
字
4.输出信息熵,平均码长以及编码效率
三、源代码
#include
#include
using namespace std;
#define MAX 100
typedef struct{
int weight;
int parent,Lc,Rc;
char data;
}HTNode,*HTree; //动态分配数组存储赫夫曼树
typedef char * *HCode;
void HuffmanCode(HTree &HT,HCode &HC,int *w,int n);
void Select(HTree &HT,int n,int &s1,int &s2);
void inputCode();
void outputCode(HCode HC,char *data,int *w,int n);
const int n=27;
int flag=0;
HTree Ht;
HCode Hc;
int num;
void HuffmanCode(HTree &HT,HCode &HC,int *w,int n){
//w存放n个字符权值(均>0),构造赫夫曼树HT,并求n个字符赫夫曼编码HC。
int m,i,s1,s2;//s1,s2为在HT[1..i-1]中parent为0且weight最小的两个结点
if(n<=1) return;//如果结点小于或等于1个,则调用函数出错,退出函数
m=2*n-1;//m为赫夫曼树的总结点数
HT=(HTree)malloc((m+1)*sizeof(HTNode));
// 对赫夫曼树进行初始化
for(i=1;i<=n;i++) {
HT[i].data=0;
HT[i].weight=w[i-1];
HT[i].parent=0;
HT[i].Lc=0;
HT[i].Rc=0;
}
for(;i<=m;i++) {
HT[i].data=0;
HT[i].weight=0;
HT[i].parent=0;
HT[i].Lc=0;
HT[i].Rc=0;
}
//***************创建HuffmanTree******************
char *cd;
int start,c,f;
for(i=n+1;i<=m;++i){
Select(HT,i-1,s1,s2);
HT[s1].parent=HT[s2].parent=i;
HT[i].Rc=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
//从叶子到根逆向求每个字符的赫夫曼编码
HC=(HCode)malloc((n+1)*sizeof(char*)); //分配n个字符编码的头指针向量
cd=(char*)malloc(n*sizeof(char)); //分配求编码的工作空间
cd[n-1]='\0'; // 编码结束符
for(i=1;i<=n;i++){ // 逐个字符求赫夫曼编码start=n-1; // 编码结束符位置
for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)// 从叶子到根逆向求编码
if(HT[f].Lc==c)
cd[--start]='0';
else
cd[--start]='1';
HC[i]=(char*)malloc((n-start)*sizeof(char));// 为第i个字符编码分配空间
strcpy(HC[i],&cd[start]); //从cd复制编码(串)到HC }
free(cd);
}//HuffmanCode
//s1为权值最小的根结点
void Select(HTree &HT,int n,int &s1,int &s2){
//在HT[1..n]选择parent为0且weight最小的两个结点,其序号分别为s1,s2。//其中s1 为weight最小值的结点,s2为weight第二小的值的结点int flag1=1,flag2=1; //s1,s2初始化后则置0;
int i;
for(i=1;i<=n;i++)
if(HT[i].parent==0&&(flag1||flag2))
if(flag1){
s1=i;
flag1=0;
}
else if(flag2){
s2=i;
flag2=0;
}
for(i=s1+1;i<=n;i++)
if(HT[i].parent==0){
if(HT[i].weight //当所比较的值比最小值小时,修改s1和s2