数据结构课程设计 实例
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《数据结构》课程设计报告书
题目:赫夫曼编码
系别:计算机科学与应用
学号:*********
学生姓名:***
指导教师:***
完成日期:2007年2月1日
一.需要分析
赫夫曼编码
自己找一篇不少于100个单词的英文文章,分析该文章中每一个字符的出现概率(包括标点符号,区分大小写),根据分析结果对文章中每一个字符进行赫夫曼编码,并将编码原则存储于一个独立的文本文件中。最后,根据这个编码原则,将英文文章转换为01串存储于一个文本文件中。
如:英文文章为aaabbc
则编码规则为a-----0
b-----10
c-----11
英文文章将被转化为000101011
有能力的同学应该再编写一个解码程序,这个就不统一要求。
二.概要设计
1.系统运行时,将有ifstream fs("n.txt")句生成一文本文件,用于存放要编码的英文文章。
2.然后,将有fs.get(c)语句从文章中逐个读入字符,其字符的ASCII码值将存入int w2[128]的对应下标中,且对应w2[i]的值加1。之后,将ASCII 码值及对应字符出现次数记录于一动态分配的机构体tongji数组*w中。
3.然后,将调用赫夫曼编码函数HuffmanCoding(HT,HC,w,n)对文章中出现的字符进行编码,并将结果存于数组HC[]中。
4.有ofstream fp("code.txt")打开勇于存储编码后的文章。
5.对01码的解码程序将有函数Decoding()执行。
三.详细设计
#include
#include
#include
#define MAX_NUM 100000
#include
typedef struct{
int index;//用于记录字符的ASCII码
int frequent;//用于记录字符出现的次数
}tongji;//该结构体用于对统计文章中字符出现的次数,及该字符对应的整数值(用于字符与编码的转换)
typedef struct{
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;//动态分配数组存储赫夫曼树
typedef char **HuffmanCode;//动态分配数组存储赫夫曼编码表
//Select()函数,用于选择两个weight最小的结点
void Select(HuffmanTree HT,int end,int *s1,int *s2)
{
//cout< int i; int min1=MAX_NUM; int min2; for (i=1;i<=end;i++) { if (HT[i].parent==0&&HT[i].weight { *s1=i; min1=HT[i].weight; } } min2=MAX_NUM; for(i=1;i<=end;i++) { if(HT[i].parent==0&&(*s1!=i)&&HT[i].weight { *s2=i; min2=HT[i].weight; } } } void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,tongji w[],int n){ //w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC if(n<=1)return; tongji *t=w+1; int m=2*n-1; HuffmanTree p;int i; HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); for(p=HT,i=1;i<=n;++i,++t) { p[i].weight=t->frequent;p[i].parent=0;p[i].lchild=0;p[i].rchild=0; }//*p={*w,0,0,0}; for(;i<=m;++i){p[i].weight=0;p[i].parent=0;p[i].lchild=0;p[i].rchild=0;}//*p={ 0,0,0,0}; int s1,s2; for(i=n+1;i<=m;++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; } //---------从叶子到根逆向求每个字符的赫夫曼编码---------------- /*int start,c,f; HC=(HuffmanCode)malloc((n+1)*sizeof(char *)); char *cd; 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(c==HT[f].lchild) cd[--start]='0'; else cd[--start]='1'; } HC[i]=(char *)malloc((n-start)*sizeof(char)); strcpy(HC[i],&cd[start]); } free(cd);//释放工作空间 */ //--------------从根到叶子求编码--------------------------------------------- HC=(HuffmanCode)malloc((n+1)*sizeof(char*));//分配n个字符编码的头指针向量 char *cd; cd=(char*)malloc(n*sizeof(char));//分配求编码的工作空间 cd[n-1]='\0';//编码结束符 int q=m;int cdlen=0; for(i=1;i<=m;++i) HT[i].weight=0;//遍历赫夫曼树时用作结点状态标志while (q){ if(HT[q].weight==0){//向左 HT[q].weight=1; if(HT[q].lchild!=0){q=HT[q].lchild; cd[cdlen++]='0';} else if(HT[q].rchild==0){//登记叶子结点的字符的编码 HC[q]=(char*)malloc((cdlen+1)*sizeof(char));//为第i个字符编码分配空间