数据结构课程设计 实例

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

相关文档
最新文档