哈弗曼编译码器 罗忠霖Word格式.docx

上传人:b****6 文档编号:16218182 上传时间:2022-11-21 格式:DOCX 页数:15 大小:164.96KB
下载 相关 举报
哈弗曼编译码器 罗忠霖Word格式.docx_第1页
第1页 / 共15页
哈弗曼编译码器 罗忠霖Word格式.docx_第2页
第2页 / 共15页
哈弗曼编译码器 罗忠霖Word格式.docx_第3页
第3页 / 共15页
哈弗曼编译码器 罗忠霖Word格式.docx_第4页
第4页 / 共15页
哈弗曼编译码器 罗忠霖Word格式.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

哈弗曼编译码器 罗忠霖Word格式.docx

《哈弗曼编译码器 罗忠霖Word格式.docx》由会员分享,可在线阅读,更多相关《哈弗曼编译码器 罗忠霖Word格式.docx(15页珍藏版)》请在冰豆网上搜索。

哈弗曼编译码器 罗忠霖Word格式.docx

stdio.h>

stdlib.h>

string.h>

conio.h>

typedefstruct

{

charchr1;

intweight;

intparent,lchild,rchild;

}HTNode,*HuffmanTree;

charchr;

intw1;

char*code;

//编码

}Ch;

//字符和对应的权值及编码

voidSelect(HuffmanTree&

HT1,intj,int&

s1,int&

s2);

voidHuffmanCoding(HuffmanTree&

HT,Ch*w,intn);

//构造哈夫曼树HT

voidencoding(HuffmanTree&

HT,Ch*ch,intn);

//求每个字符的哈夫曼编码

voidEncoding(Ch*ch1,intn);

voidDecoding(HuffmanTree&

HT,intsum);

//译码

voidcaidan();

voidPrintf();

voidmain()

FILE*p;

intchoice,n1,w2=1;

inti,flag=1,m;

charch;

HuffmanTreeHTr;

Ch*c;

caidan();

while(flag)

{

loop:

printf("

\n*请选择(0-5):

"

);

scanf("

%d"

&

choice);

switch(choice)

{

case1:

printf("

请输入字符集大小n="

scanf("

n1);

c=(Ch*)malloc((n1+1)*sizeof(Ch));

flushall();

for(i=1;

i<

=n1;

i++)

{

printf("

请输入字符及其权值:

scanf("

%c%d"

ch,&

w2);

c[i].chr=ch;

c[i].w1=w2;

flushall();

}

HuffmanCoding(HTr,c,n1);

encoding(HTr,c,n1);

break;

case2:

Encoding(c,n1);

case3:

Decoding(HTr,n1);

case4:

Printf();

case5:

m=2*n1-1;

if((p=fopen("

TreePrint.txt"

"

w"

))==NULL)

Filecouldnotbeopened\n"

else

{

fprintf(p,"

\n哈夫曼树的构造如下所示:

\n"

结点weightparentlchildrchild"

for(i=1;

i<

=m;

i++)

{

fprintf(p,"

\n%4d%8d%8d%8d%8d"

i,HTr[i].weight,

HTr[i].parent,HTr[i].lchild,HTr[i].rchild);

}

}

fclose(p);

printf("

for(i=1;

{

HTr[i].parent,HTr[i].lchild,HTr[i].rchild);

break;

case0:

flag=0;

你选择了推出程序,欢迎使用!

break;

default:

gotoloop;

}

}

}

voidcaidan()

{printf("

\n*****************哈夫曼编译器*****************\n"

printf("

1.初始化\n"

2.编码\n"

3.译码\n"

4.打印代码文件\n"

5.打印哈夫曼树\n"

6.退出系统\n"

**********************************************\n"

s2)

//在HT[1...j]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2

inti=0,d=0,h;

for(i=j;

i>

=0;

i--)

{

if(HT1[i].parent!

=0)//在双亲不为0的条件下

continue;

if(d==0)//用s1记录第一个双亲为0的元素所在的位置

s1=i;

d++;

}

elseif(d==1)//用s2记录第而个双亲为0的元素所在的位置

{

s2=i;

elseif(d==2)

{

if(HT1[s1].weight<

=HT1[s2].weight)//s2用于存储最小值的位置

{

h=s1;

s1=s2;

s2=h;

}

if(HT1[i].weight<

HT1[s1].weight)//s1用于存放次小值的位置

s1=i;

}

HT,Ch*w,intn)

//*w存放n个字符的权值(均>

0),构造哈夫曼树HT

FILE*p;

inti,j,m,s1,s2;

if(n<

=1)return;

m=2*n-1;

//树的结点总数

HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));

//0号单元未用

for(i=1;

=n;

i++)

{//初始化

HT[i].chr1=w[i].chr;

HT[i].weight=w[i].w1;

//

HT[i].parent=0;

HT[i].lchild=0;

HT[i].rchild=0;

for(i=n+1;

HT[i].weight=0;

i++)//建哈夫曼树

//在HT[1...i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2。

Select(HT,i-1,s1,s2);

HT[s1].parent=i;

HT[s2].parent=i;

HT[i].lchild=s1;

HT[i].rchild=s2;

HT[i].weight=HT[s1].weight+HT[s2].weight;

if((p=fopen("

hfmTree.txt"

else

fprintf(p,"

fprintf(p,"

i,HT[i].weight,

HT[i].parent,HT[i].lchild,HT[i].rchild);

fclose(p);

HT,Ch*ch,intn)

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

inti,c,f,start;

char*cd;

cd=(char*)malloc(n*sizeof(char));

//分配求编码的工作空

cd[n-1]='

\0'

;

//编码结束符。

++i)//逐个字符求哈夫曼编码

start=n-1;

//编码结束符位置

for(c=i,f=HT[i].parent;

f!

c=f,f=HT[f].parent)//从叶子到根逆向求编码

if(HT[f].lchild==c)cd[--start]='

0'

elsecd[--start]='

1'

ch[i].code=(char*)malloc((n-start)*sizeof(char));

//为第i个字符编码分配空间

strcpy(ch[i].code,&

cd[start]);

//从cd复制编码(串)到code

free(cd);

//释放工作空间

}

voidEncoding(Ch*ch1,intn)

//利用已经建立的哈弗曼树编码对输入的字符进行哈弗曼编码

FILE*q1,*q2;

//chara[100];

//用于存放输入的字符

charnum[1000],c;

char*p=num;

//用于存放字符对应的哈弗曼编码

inti,j;

if((q1=fopen("

ToBeTran.txt"

r"

rewind(q1);

while(!

feof(q1))//依次判断字符的对应的哈弗曼编码

c=fgetc(q1);

for(j=1;

j<

j++)

if(c==ch1[j].chr)

printf("

%c:

%s"

ch1[j].chr,ch1[j].code);

strcpy(p,ch1[j].code);

p=p+strlen(ch1[j].code);

}//如果找到就把对应的哈弗曼编码复制到字符数组num中

*p='

\n得到的编码是:

for(i=0;

num[i]!

='

i++)//输出字符对应的哈弗曼编码

if(i==50)printf("

//当输出50个字符时,进行换行

%c"

num[i]);

fclose(q1);

if((q2=fopen("

CodeFile.txt"

i=0;

while(num[i]!

if(i==50)fprintf(q2,"

fprintf(q2,"

num[i++]);

fclose(q2);

HT,intsum)//译码

{

//charcode1[1000];

//用于存放输入的密码

chara1[100],c;

//用于存放翻译好的字符

intn=0,i=0,b=2*sum-1;

r+"

feof(p))

c=fgetc(p);

if(c=='

)b=HT[b].lchild;

//当遇到0时指向哈弗曼树的左子树

)b=HT[b].rchild;

//当遇到1时指向哈弗曼树的右子树

if(HT[b].lchild==0&

&

HT[b].rchild==0)//当左右子树均为空时表明已找到对应的字符

a1[n++]=HT[b].chr1;

b=2*sum-1;

//将对应的字符放在数组a1中,并重新设置b的值继续翻译

a1[n]='

i=0;

while(a1[i]!

)//输出翻译好的字符

a1[i++]);

TextFile.txt"

得到的翻译结果是:

while(a1[i]!

if(i==50)fprintf(p,"

voidPrintf()

FILE*p;

得到的编码是:

feof(p))

inti=0;

if(i==50)printf("

printf("

fgetc(p));

i++;

 

4.结果显示:

四、实验小结及体会:

通过本实验能够更好掌握文件指针的操作运用,加深理解,运用它解决一些实际问题,且能教熟练掌握数的结构以及哈弗曼算法。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 教育学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1