哈夫曼编码实验报告

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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

相关文档
最新文档