有谁可以用c语言做个哈夫曼编码和译码的课程设计 带图形界面的(我是学数据结构的) 100

题目:哈夫曼树应用功能:1.从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树并将它存于文件hfmTree中.将已在内存中的哈夫曼树以直观的方式(比如树)显示在... 题目: 哈夫曼树应用
功能:
1.从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树并将它存于文件hfmTree中.将已在内存中的哈夫曼树以直观的方式(比如树)显示在终端上;
2.利用已经建好的哈夫曼树(如不在内存,则从文件htmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中,并输出结果,将文件CodeFile以紧凑格式先是在终端上,每行50个代码。同时将此字符形式的编码文件写入文件CodePrint中。
3.利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中,并输出结果。

分步实施:
1) 初步完成总体设计,搭好框架,确定人机对话的界面,确定函数个数;
2) 完成最低要求:完成功能1;
3) 进一步要求:完成功能2和3。有兴趣的同学可以自己扩充系统功能。
要求:1)界面友好,函数功能要划分好
2)总体设计应画一流程图
3)程序要加必要的注释
4) 要提供程序测试方案
5) 程序一定要经得起测试,宁可功能少一些,也要能运行起来,不能运行的程序是没有价值的。
最主要的是界面问题!我就是不会做图形界面!
展开
 我来答
Baigle一下
2009-06-30 · 超过10用户采纳过TA的回答
知道答主
回答量:80
采纳率:0%
帮助的人:32.8万
展开全部
是树的课后实习题么???
实习题我有答案
#include<stdio.h>
#include<stdlib.h>
typedef struct hfmtree
{
char data;//值
int weight;//权
struct hfmtree *parent,*lchild,*rchild;//双亲,左孩子,右孩子
}hfmtree;
main()
{
hfmtree* huffmancoding(hfmtree *hf,int i,int *wei,char *da);//构造赫夫曼树
void treeprin(hfmtree *hf);//将赫夫曼树的图存放在c:\\treeprint.txt文件中
void Printcode(hfmtree *hf);//打印代码文件
void storage(hfmtree *hf);//将赫夫曼树储存到hfmtree.txt文件中
void Storedcode(hfmtree *hf);//进行编码操作,并将结果存放到c:\\code file.txt中,要进行翻译的文件存放在c:\\tobetran.txt;
void coding(hf);//进行译码
hfmtree *hf;
int i,j,*wei,flag1=1,flag2=1;
char *da,ch;//分别记录值以及权值
FILE *fp;//用来判断必备的文件是否存在
printf("由于是第一次进行赫夫曼树构造所以必须进行初始化操作\n");//**********************************************************
printf("请依次输入构成赫夫曼树的值,'#'为结束输入\n");
i=1;
hf=NULL;
if(!(da=(char *)malloc((i+1)*sizeof(char))))exit(1);
fflush(stdin);
scanf("%c",&da[i]);//0号单元舍弃
while(da[i]!='#')//输入值
{
i++;
if(!(da=(char *)realloc(da,(i+1)*sizeof(char))))exit(1);
fflush(stdin);
scanf("%c",&da[i]);
}
i--;
printf("请输入对应的权值\n");
if(!(wei=(int *)malloc((i+1)*sizeof(int))))exit(1);
for(j=1;j<=i;j++)//0号单元舍弃
{
fflush(stdin);
scanf("%d",&wei[j]);
}
hf=huffmancoding(hf,i,wei,da);
storage(hf);//*********************************以上为初始化赫夫曼树************************************
printf("恭喜你赫夫曼树已经成功建立具体情况请查看hfmtree.txt文件\n");
while(flag1)
{
printf("接下来要进行什么操作?\nE:编码\nD:译码\nP:印代码文件\nT:印赫夫曼树\nQ:退出系统");
while(flag2)
{
fflush(stdin);
scanf("%c",&ch);
system("cls");
switch(ch)
{
case 'E':flag2=0;Storedcode(hf);break;//编码
case 'e':flag2=0;Storedcode(hf);break;
case 'D':fp=fopen("c:\\codefile.txt","r");if(fp==NULL)printf("对不起,您是否先考虑一下先进行编码操作呢?没有东西让我翻译啊\n");else coding(hf);flag2=0;break;//译码,但前提必须存在指定文件
case 'd':fp=fopen("c:\\codefile.txt","r");if(fp==NULL)printf("对不起,您是否先考虑一下先进行编码操作呢?没有东西让我翻译啊\n");else coding(hf);flag2=0;break;
case 'p':fp=fopen("c:\\textfile.txt","r");if(fp==NULL)printf("对不起,您是否先考虑一下先进行译码操作呢?没有东西让我翻译啊\n");else Printcode(hf);flag2=0;break;//打印编码,前提必须存在指定文件
case 'P':fp=fopen("c:\\textfile.txt","r");if(fp==NULL)printf("对不起,您是否先考虑一下先进行译码操作呢?没有东西让我翻译啊\n");else Printcode(hf);flag2=0;break;
case 't':treeprin(hf);flag2=0;break;
case 'T':treeprin(hf);flag2=0;break;
case 'q':flag1=0;flag2=0;break;
case 'Q':flag1=0;flag2=0;break;
default:printf("输入错误,请重新输入\nE:编码\nD:译码\nP:印代码文件\nT:印赫夫曼树\nQ:退出系统");
}
}
flag2=1;
}
fclose(fp);
printf("是否保留文件?(y/n)\n");
flag1=1;
while(flag1)
{
fflush(stdin);
scanf("%c",&ch);
if(ch=='n'||ch=='N')
{
i=1;
flag1=0;
}
else if(ch=='y'||ch=='Y')
{
i=0;
flag1=0;
}
else
printf("输入错误,请重新输入\n");
}
if(i)
{
system("erase c:\\hfmtree.txt");
system("erase c:\\tobetran.txt");
system("erase c:\\codefile.txt");
system("erase c:\\textfile.txt");
system("erase c:\\codeprin.txt");
system("erase c:\\treeprint.txt");
}
}
void select(hfmtree *hf,int i,int *s1,int *s2)//取hf中权值最小的2个数
{
int k,m=2;
*s1=*s2=0;
for(k=1;k<=i;k++)
{
if(hf[k].parent==NULL)//给s1,s2赋予初值
{
if(m!=0)
{
if(m==2)
*s1=k;
if(m==1)
*s2=k;
m--;
continue;
}
if(hf[k].weight<=hf[*s1].weight||hf[k].weight<=hf[*s2].weight)//判断大小
{
if(hf[*s1].weight<=hf[*s2].weight)
{
*s2=*s1;
*s1=k;
}
else
{
*s1=*s2;
*s2=k;
}
}
}
}
if(hf[*s1].weight>hf[*s2].weight)//始终保证左孩子比右孩子小
{
k=*s1;
*s1=*s2;
*s2=k;
}
}
hfmtree* huffmancoding(hfmtree *hf,int i,int *wei,char *da)//构造赫夫曼树,并将形成的赫夫曼树以先序顺序记录在hfmtree文件中
{
hfmtree *p;
int m,j,*s1,*s2,a,b;
s1=&a,s2=&b;
if(i<=1)
{
printf("元素太少,无法构成赫夫曼树.\n");
exit(1);
}
m=2*i-1;
if(!(hf=(hfmtree *)malloc((m+1)*sizeof(hfmtree))))exit(1);
for(p=hf,j=1;j<=i;j++)//对叶子结点赋值
{
(p+j)->data=da[j];
(p+j)->weight=wei[j];
(p+j)->lchild=NULL;
(p+j)->rchild=NULL;
(p+j)->parent=NULL;
}
for(j=i+1;j<=m;j++)//非叶子结点赋值
{
(p+j)->data='@';//对于那些非叶子节点可随便进行一些特殊赋值如@,#,$,^之类的符号
(p+j)->weight=0;
(p+j)->lchild=NULL;
(p+j)->rchild=NULL;
(p+j)->parent=NULL;
}
for(j=i+1;j<=m;j++)
{
select(hf,j-1,s1,s2);//找权值最小的2个数
hf[*s1].parent=hf+j,hf[*s2].parent=hf+j;//2个最小的数的双亲是j
hf[j].weight=hf[*s1].weight+hf[*s2].weight;//j的权等于他的左右结点的和
hf[j].lchild=hf+(*s1),hf[j].rchild=hf+(*s2);//j的左右结点
}
return(hf+m);//赫夫曼树完成后最后一个结点恰恰是赫夫曼树的根结点
}
void preordertraverse(hfmtree *hf,char *ch,int *i)
{
if(hf)
{
(*i)++;
if(!(ch=(char *)realloc(ch,(*i+3)*sizeof(char))))exit(1);//将本节点输入到ch中
ch[*i-1]=hf->data;
preordertraverse(hf->lchild,ch,i);
preordertraverse(hf->rchild,ch,i);
}
else//本节点是空节点则输入0
{
(*i)++;
if(!(ch=(char *)realloc(ch,(*i+3)*sizeof(char))))exit(1);
ch[*i-1]='0';
}
}
void storage(hfmtree *hf)//将赫夫曼树储存到hfmtree.ini文件中
{
FILE *pf;
char *ch;
int *i,a,j;
i=&a;
a=0;
if(!(ch=(char *)malloc(sizeof(char))))exit(1);
preordertraverse(hf,ch,i);
ch[*i]='#';//为以后构造赫夫曼树留作二叉树结束标志
pf=fopen("c:\\hfmtree.txt","w");
for(j=0;j<=*i;j++)
fputc(ch[j],pf);//将赫夫曼树以先序创建的形式输入到c:\\hfmtree.txt中
fclose(pf);//脱钩
}
void Fordecoding(hfmtree *ht,int *j,int *i,char coding[20],char data,int l)//对单个字母进行编码
{
if(*j==1&&ht)
{
if(ht==ht->parent->lchild)//右1左0
coding[l++]='0';
else
coding[l++]='1';
if(ht->data==data)//如果是那就将*j赋予0将所有正在递归操作的函数全部停止
{
*j=0;
*i=l;
}
Fordecoding(ht->lchild,j,i,coding,data,l);//左孩子递归
Fordecoding(ht->rchild,j,i,coding,data,l);//右孩子递归
}
}
void Storedcode(hfmtree *ht)//对输入的文件进行译码操作
{
int i,j,*k,a,*m,b,l;
char *ch,coding[20],data;
hfmtree q;
FILE *fp;
q.lchild=ht;//给根设立个头结点
ht->parent=&q;
q.rchild=NULL;
m=&b;
k=&a;
a=1;
printf("请输入要进行编译的文件,'#'为结束输入\n");
i=1;
if(!(ch=(char *)malloc(i*sizeof(char))))exit(1);
fflush(stdin);
scanf("%c",&ch[i-1]);
while(ch[i-1]!='#')//进行文件输入
{
i++;
if(!(ch=(char *)realloc(ch,i*sizeof(char))))exit(1);
fflush(stdin);
scanf("%c",&ch[i-1]);
}
fp=fopen("c:\\tobetran.txt","w");//把输入的文件存放到c:\\tobetran中
for(j=0;j<i;j++)//将'#'去掉
fputc(ch[j],fp);
fclose(fp);//脱钩
j=0;
data=ch[j++];
fp=fopen("c:\\codefile.txt","w");//将得到的译码写入次文件中
while(data!='#')
{
*k=1;//要调用的函数的结束标志
l=0;//coding数组从0开始计数
Fordecoding(ht,k,m,coding,data,l);
for(i=1;i<*m;i++)//把翻译过来的密码输入文件中
{
printf("%c",coding[i]);
fputc(coding[i],fp);
}
printf(" ");
data=ch[j++];//取此时的字母
}
fclose(fp);//脱钩
printf("\n");
}
void coding(hfmtree *hf)//译码
{
FILE *fp,*pf;
hfmtree *p;
char ch;
p=hf;
fp=fopen("c:\\codefile.txt","r");//读取存放译码的文件
pf=fopen("c:\\textfile.txt","w");//将编译完成的代码要写入的文件
ch=fgetc(fp);
while(ch!=EOF)//进行译码
{
if(ch!=EOF)
{
if(ch=='0')//向左走
p=p->lchild;
else//向右走
p=p->rchild;
}
if(!p->lchild&&!p->rchild)//非叶子结点
{
printf("%c",p->data);
fputc(p->data,pf);//输入到c:\\textfile.txt"文件中
p=hf;
}
ch=fgetc(fp);
}
printf("\n");
fclose(fp);
fclose(pf);
}
void Printcode(hfmtree *hf)//打印代码文件
{
FILE *fp,*pf;
char ch;
int i=0;
printf("进行印代码文件操作\n");
fp=fopen("c:\\textfile.txt","r");//读取存放代码的文件
pf=fopen("c:\\codeprin.txt","w");//将代码文件重新写入到这里
ch=fgetc(fp);
while(ch!=EOF)
{
printf("%c",ch);
i++;
if(i%50==0)
printf("\n");
fputc(ch,pf);//将这个字母输入进去
ch=fgetc(fp);//取下一个字母
}
fclose(pf);//脱钩
fclose(fp);
printf("\n");
}
int preordertraverse1(int i,char a[100][100],hfmtree *hf,int j)//进行二叉树的图的构造
{
int k,m,n;
m=n=0;
if(hf)
{
m=preordertraverse1(i+1,a,hf->rchild,j);
k=m+j;
n=preordertraverse1(i+1,a,hf->lchild,k+1);
a[k][i]=hf->data;
return(m+n+1);
}
else
return(0);
}
void treeprin(hfmtree *hf)//将赫夫曼树的图写入c:\\treeprin.txt文件中
{
char tree[100][100];
int i,j;
FILE *pf;
pf=fopen("c:\\treeprin.txt","w");
for(i=0;i<100;i++)
for(j=0;j<100;j++)
tree[i][j]='#';
preordertraverse1(0,tree,hf,0);//对此时的赫夫曼树进行造图操作
for(i=0;i<100;i++)
{
for(j=99;j>=0;j--)
{
if(tree[j][i]=='#')
fputc(' ',pf);
else
{
if(tree[j][i]==' ')
fputc('^',pf);
else
fputc(tree[j][i],pf);
}
}
printf("\n");
fputc('\n',pf);
}
fclose(pf);
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式