您的位置:首页 > 理论基础 > 数据结构算法

数据结构课程设计-12月30号

2015-12-30 23:21 453 查看
今天晚上算是三天课设集一晚来学习,把代码分析,当然代码也是参照同学的,放这里其实也希望能帮到更多同学吧

自己修改了小小的地方,然后给程序加注释,因为明天早上要给老师讲解的

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#define N 100
#define M 2*N

struct Infor		/*字符--权值*/
{
char ch;						/*存储字符*/
int  weight;					/*该字符的权值*/
}Infor
;							/*结构体数组*/

typedef struct						/*哈夫曼树的定义*/
{
int weight;						/*结点的权值*/
int parent;
int LChild;
int RChild;
}HTNode,HuffmanTree[M];

int length;												/*0号单元不用*/
typedef char * HuffmanCode[N+1];						/*记录文件中不相同字符的个数*/

void Select(HuffmanTree ht,int n,int *s1,int *s2)	/*s1里面存的是权值最小的下标,s2里面存的是权值第二小的下标*/
{
int i;
for(i=0;i<=n;i++)
if(ht[i].parent==0){
*s1=i;
break;
}
for(i=i+1;i<=n;i++)
if(ht[i].parent==0){				/*找双亲为0,找到就退出然后去判断*/
*s2=i;
break;
}
for(i=i+1;i<=n;i++){
if(ht[i].parent==0 && ht[i].weight<*s2)			/*确定最小和次小坐标*/
{
if(ht[i].weight<*s1)
{
*s2=*s1;
*s1=i;
}
else
*s2=i;
}
}
}

void ReadFile()/*读文件的函数*/
{
FILE *fp;
char c;
int i=0,j=0;
fp=fopen("data.txt","r");
while((c=fgetc(fp))!=EOF)/*读文件的操作*/
{
for(i=0;i<j;i++)
if(Infor[i].ch==c)				/*如果字符之前出现了,所对应权值+1,也就是在这里统计*/
{
Infor[i].weight++;
break;
}
if(i==j)
{
Infor[j].ch=c;					/*读取一个字符,往字符权值结构体里写入一个*/
Infor[j].weight++;
j++;
}
}
fclose(fp);
length=j;					//这就是有多少个权值

}

void CrtHuffmanTree(HuffmanTree ht,struct Infor Infor[],int n)				/*哈夫曼树的创建*/
{
int i,m;
int s1,s2;
m=2*n-1;
for(i=1;i<=n;i++)			/*初始化前n个元素成为根结点*/
{
ht[i].weight=Infor[i-1].weight;
ht[i].LChild=ht[i].RChild=ht[i].parent=0;
}
for(i=n+1;i<=m;i++)			/*初始化后n-1个空元素*/
ht[i].weight=ht[i].LChild=ht[i].RChild=ht[i].parent=0;
for(i=n+1;i<=m;i++)
{
Select(ht,i-1,&s1,&s2);					/*在ht的前i-1项中选双亲为0且权值最小的两结点*/
ht[i].weight=ht[s1].weight+ht[s2].weight;			/*建新结点,赋权值*/
ht[i].LChild=s1;
ht[i].RChild=s2;						/*赋新结点左右孩子指针*/
ht[s1].parent=ht[s2].parent=i;			/*改s1,s2的双亲指针*/
}
}

void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n)/*哈夫曼编码的创建*/
{
char *cd;
int i,start,c,p;
cd=(char *)malloc((n+1)*sizeof(char));				/*临时编码数组*/
cd[n-1]='\0';							/*从后向前逐位求编码,首先放编码结束符*/
for(i=1;i<=n;i++)						/*从每个叶子开始,求相应的哈夫曼编码*/
{
start=n-1;
c=i;p=ht[i].parent;					/*c为当前结点,p为其双亲*/
while(p!=0)
{
--start;
if(ht[p].LChild==c) cd[start]='0';			/*左分支得'0'*/
else
cd[start]='1';							/*右分支得'1'*/
c=p;
p=ht[p].parent;								/*上溯一层*/
}
hc[i]=(char *)malloc((n-start)*sizeof(char));		/*动态申请编码串空间*/
strcpy(hc[i],&cd[start]);							/*复制编码*/
}
free(cd);
}

void WrtCodeFile(struct Infor Infor[],HuffmanCode hc,int n)/*把哈夫曼编码写入文件中*/
{
FILE *fp1,*fp2;
int i;
char c;
fp1=fopen("data.txt","r");
fp2=fopen("codeFile.txt","w");
printf("输出哈夫曼编码\n");
while((c=fgetc(fp1))!=EOF){
for(i=0;i<n;i++)
if(Infor[i].ch==c)						/*当权值所对应的字符与文件所读取的字符相同*/
{
fprintf(fp2,"%s",hc[i+1]);			/*把这个位上所对应的编码写入到文件中*/
printf("%s",hc[i+1]);
break;
}
}
fclose(fp1);
fclose(fp2);
}

void WrtDecodeFile(HuffmanCode hc,struct Infor Infor[],int n)/*哈夫曼译码后写入文件*/
{
int i,j=1;
char c;
char cd
;
FILE *fp1,*fp2;
fp1=fopen("codeFile.txt","r");
fp2=fopen("decodeFile.txt","w");
printf("输出哈夫曼译码\n");
while((c=fgetc(fp1))!=EOF)
{
cd[j]='\0';
cd[j-1]=c;
for(i=1;i<=n;i++)
{
if(strcmp(hc[i],cd)==0)					/*这里和上面是反过来的,如果一编码串和读取到的编码串相同*/
{
fprintf(fp2,"%c",Infor[i-1]);		/*则在字符串权值结构体中找到对应的字符写入文件*/
printf("%c",Infor[i-1]);
j=1;
break;
}
}
if(i==n+1)
j++;
}
fclose(fp1);
fclose(fp2);
}
int main()
{
HuffmanTree ht;
HuffmanCode hc;
ReadFile();								/*读文本里的内容获取字符权值*/
CrtHuffmanTree(ht,Infor,length);		/*创建哈夫曼树*/
CrtHuffmanCode(ht,hc,length);			/*将哈夫曼编码写入hc中*/
WrtCodeFile(Infor,hc,length);			/*将哈夫曼编码写入文件中*/
printf("\n");
WrtDecodeFile(hc,Infor,length);			/*将编码文件里的内容译码并写入文件*/
printf("\n");
}
还要继续理解代码

总得来说课设今晚是最锻炼人的,看我认真起来还是可以的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: