数据结构之线性表的应用
1.实验题目
利用哈夫曼编码进行通信可以大大提高信道利用率,这要求在发送端通过一个编码系统对待传输预先编码,在接收端将传来的数据进行译码。对于双工通道,每端都需要一个完整的编/译码系统。
2.需求分析
本演示程序用TC编写,完成单链表的生成,任意位置的插入、删除,以及确定某一元素在单链表中的位置。
① 输入的形式和输入值的范围:根据程序所给的提示输入字符的种类数、想要编码的字符串、想译码的哈夫曼码。输入的字符串中字符的种类一定要和输入的种类数对应,否则会造成程序的错误。
② 输出的形式:首先会输出第一次输入字符串中各字符出现的次数,并给出每个字符的哈夫曼码;之后再输出的就是对应于用户输入的哈夫曼码的译码字符以及再次输入一串字符串后编码得到的哈夫曼码。
③ 程序所能达到的功能:哈夫曼树的初始化,用已构造的哈夫曼树实现哈夫曼码的编/译码及输出。
④ 测试数据:字符数为4,第一次字符串为qweqqqrtyeruiy。需要译码的哈夫曼码为100001001001111010101110001,进行编码的字符串为yretweqt。
3.概要设计
1)为了实现上述程序功能,需要定义哈夫曼树的抽象数据类型:
ADT Tree{
数据对象:D是具有相同特性的数据元素的集合。
数据关系:R={H},(Di,{Hi})。
HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int n)
操作结果:构造赫夫曼树HT,n个字符编码HC
select(HuffmanTree t,int i,int &s1,int &s2)
初始条件:哈夫曼树HT已存在
操作结果:使s1为较小的值
min(HuffmanTree t,int i)
初始条件:哈夫曼树HT已存在
操作结果:被函数void select()调用取小。
Creatree(BT &p,char c)
操作结果:采用递归方式构造一棵二叉排序树。
InOrderTraverse(BT p)
初始条件:二叉排序树BT已存在。
操作结果:中序遍历。
DispHCode(HuffmanTree HT,HuffmanCode HC,int n)
初始条件:哈夫曼树HT已存在。
操作结果:显示哈弗曼码。
Tran(HuffmanTree HT,int n)
初始条件:哈夫曼树HT已存在。
操作结果:将哈夫曼码译码为字符串。
TTranChar(HuffmanTree HT,HuffmanCode HC,int n)
初始条件:哈夫曼树HT已存在。
操作结果:将字符串整体编码成哈夫曼码。
}
2)本程序包含9个函数:
①主函数main()
②哈夫曼树构造HuffmanCoding()
③取小排序select()
④遍历取小min()
⑤构造二叉排序树Creatree()
⑥中序遍历排序树InOrderTraverse()
⑦输出哈夫曼编码DispHCode()
⑧将哈夫曼码译码成字符Tran()
⑨将字符串编码成哈夫曼码TTranChar()
4.详细设计
实现概要设计中定义的所有的数据类型,对每个操作给出伪码算法。对主程序和其他模块也都需要写出伪码算法。
1)结点类型和指针类型
1 typedef struct 2 3 { unsigned int weight;char data; 4 5 unsigned int parent,llchild,rrchild; 6 7 }HTNode,*HuffmanTree; 8 9 typedef char * *HuffmanCode; 10 11 typedef struct tnode 12 13 { char ch; 14 15 int count; 16 17 struct tnode *lchild,*rchild; 18 19 }BTree,*BT;
2)二叉树的基本操作
1 void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int n) 2 3 {构造赫夫曼树HT,n个字符编码HC; 4 5 在HT[1~i-1]中选择parent为0且weight最小的两个,分别s1、s2; 6 7 strcpy(HC[i],&cd[start])函数进行复制; 8 9 } 10 11 void select(HuffmanTree t,int i,int &s1,int &s2) 12 13 { if(s1>s2) 14 15 {j=s1; 16 17 s1=s2; 18 19 s2=j; 20 21 } 22 23 } 24 25 int min(HuffmanTree t,int i) 26 27 { unsigned int k=100;取k比任何权值都大 28 29 for(j=1;j<=i;j++) 30 31 if(t[j].weight<k&&t[j].parent==0) 32 33 k=t[j].weight,flag=j; 34 35 t[flag].parent=1;} 36 37 void Creatree(BT &p,char c) 38 39 { 采用递归方式构造一棵二叉排序树 40 41 if(p==NULL) 42 43 { p=(BTree * )malloc(sizeof(BTree)); 44 45 p->ch=c; 46 47 p->count=1; 48 49 p->lchild=p->rchild=NULL; 50 51 } 52 53 else 54 55 if(c==p->ch) p->count++; 56 57 else 58 59 if(c<p->ch) Creatree(p->lchild,c); 60 61 else Creatree(p->rchild,c);} 62 63 void InOrderTraverse(BT p) 64 65 {中序遍历 66 67 InOrderTraverse(p->lchild); 68 69 {printf("%c的个数为:%d ",p->ch,p->count); 70 71 s[b]=p->count;b++; 72 73 str[a]=p->ch;a++;} 74 75 InOrderTraverse(p->rchild)} 76 77 void DispHCode(HuffmanTree HT,HuffmanCode HC,int n) 78 79 {显示哈夫曼编码 80 81 printf("%c: ",HT[i].data) 82 83 } 84 85 void Tran(HuffmanTree HT,int n) 86 87 { while(cc[j]!='#') 88 89 { 90 91 if(cc[j]=='0') 92 93 i=HT[i].llchild; 94 95 else 96 97 i=HT[i].rrchild; 98 99 if(HT[i].llchild==0) 100 101 { 102 103 printf("%c",HT[i].data);i=2*n-1; } 104 105 j++;} 106 107 } 108 109 void TTranChar(HuffmanTree HT,HuffmanCode HC,int n) 110 111 { while(ss[i]!='