1、pare nt22程序流程(或程序结构、或类关系图等表明程序构成的内容, 一般为流程图等)221.流程图开始输入进行编码的字符串统计各个字符的频度,并对各叶子节点 的权重赋值初始化各节点的 Lchild, Rchild和pare nt进行哈弗曼编码该节点是否为根节点否对字符串进行编码找到当前字符编码,复制到总编码中是否最后一个字符输岀各字符串编码对哈弗曼码进行译码输岀译码结果计算分析内存占用情况if输出占用情况结束2.2.1 .伪代码1.输入进行编码的字符串2遍历字符串,并为叶子节点权重赋值3. 依次对各字符进行哈弗曼编码,自下往上,若是双亲节点左孩子则编码前插入 0若是双亲节点右孩子则编码钱
2、插入 14. 显示各字符的哈弗曼编码。5. 对字符串进行编码,挨个遍历字符,找到相应的编码,复制到总的编码里,最后输出 字符串的编码6. 对字符串的哈弗曼码进行译码。自上往下,若是 0则递归到左孩子,若是 1 则递归到右孩子,知道叶子节点,输出该叶子节点代表字符,再继续遍历。7分析内存占用情况。若用 ASCII编码,每个字符占1个字节,即8bit,该情况下占用 内存就是(字符长度)*8。若用哈弗曼编码,占用内存是各(字符频度) * (每个字符占用 位数)之和。2.3关键算法分析该程序关键算法即哈弗曼编码,语句如下:void CHTree:huffma ncode()int i;if(n=1)r
3、eturn;m=2* n-1;for(i=1;i=n;i+)叶子节点的初始化 hti.pare nt=0;htichild=0;hti .rchild=0;for(;=m;i+) /非叶子节点的初始化hti .weight=0;hti.pare nt=0;hti .lchild=0;for(i=n+1;+i) 构造哈夫曼树s1= select(i-l);/函数在ht1到hti-1中选择pare nt为0且weight最小的结点, 并将结点序号返s,并将hts1.parent设为-1s2=select(i-1);hts1.pare nt=i;hts2.pare nt=i;htichild=s1;
4、hti.rchild=s2;hti.weight=hts1.weight+hts2.weight;int c,f;+i) for(c=i,f=hti.pare nt;f!=O;c=f,f=htf.pare nt) 逆向求叶子结点的哈夫曼编码if(htf.lchild=c)stri.insert(0,0,0,1);/ 在字符串 stri的第 0 位置插入字符 “ 0”else1/ 在字符串 stri的第 0 位置插入字符“ 1 ” 分析:这段语句实现的功能是根据统计出来的各字符的频度, 建立哈弗曼。建立哈弗曼树的过程如程序所展示, 每次选取权重最小且无双亲节点的节点组合, 并将其权重之和赋给其双
5、亲节点,加入到总结中进行下次判断。 哈弗曼树建立完全以后, 开始对各字符进行编码,从下往上,以叶子节点为起始点,若它是双亲节点的左孩子,其编码前插入 0若是右孩子则插入1再判断双亲节点使其双亲节点的左孩子还是右孩子,以此类推直到根节点。 依次对每个字符进行上述过程编码。算法复杂度:最好情况为只有根结点和叶子节点: O (n)最坏情况为满二叉树情况: O (n*logn/23程序运行结果分析Rr 码译咼 ulnFT 輿诃 * 析 riiH=1%请轿乂己同词的宇符串 日扯咅门冋日吉片也出ph竺i璇迦I- S 宇行飞喰 1&9SUfieVAdrp詁isfratB內dgjEfit計vfemil swd
6、i-D J0lCPWjedt5?hulfEajcWebugJhSiwr首先,要求用户输入进行编码的字符串,遍历字符串,并为叶子节点权重赋值。然后,依次对各字符进行哈弗曼编码,自下往上,若是双亲节点左孩子则编码前插入 0若是双亲节点右孩子则编码钱插入1屏幕上显示各字符的哈弗曼编码。接下来对字符串进行编码, 挨个遍历字符,找到相应的编码,复制到总的编码里,最后输出字符串的编码。对字符串的 哈弗曼码进行译码。自上往下,若是 0则递归到左孩子,若是1则递归到右孩子,知道叶子节点,输出该叶子节点代表字符, 再继续遍历。最后分析内存占用情况。 若用ASCII 编码,每个字符占1个字节,即8bit,该情况下
7、占用内存就是(字符长度) *8。若用哈弗曼编码,占用内存是各(字符频度) * (每个字符占用位数)之和。3. 总结4.1实验的难点和关键点本实验的难点和关键点是进行哈弗曼的编码与译码。 编码之前先要遍历字符串,并统计各字符出现的频度。 这里就要区分目前的字符是否出现过, 若出现过则字符权重加一, 若没有出现则在结构体数组的当前末尾添加该元素。 统计完频度以后开始编码。 根据哈弗曼树的特点,每次选取结点里权重最小,且双亲不为 0的节点结合,依次添加直至根节点。编码过程是从下往上。对于某字符所在叶子节点,若是双亲节点左孩子则编码前插入 0若是双亲节点右孩子则编码钱插入 1。直到双亲节点移动到根节点
8、, 所得到的编码即为该字符的编码。译码过程是编码的逆过程。依次读取哈弗曼码,自上往下,若是 0则递归到左孩 子,若是1则递归到右孩子,知道叶子节点,输出该叶子节点代表字符,再继续遍历。4.2心得体会并且熟悉了这种数通过哈弗曼树的程序编写,更加深入了解了树这种数据结构的特点, 据结构的应用。同时,也对哈弗曼编码的优越性能有了根本的解释。附:程序代码#in cludestri ngusing n amespace std;#define max 1000哈夫曼数存储的最大叶子节点数 int judge;/初始化过程中用于判断字符是否出现过 struct HTNodechar c;int weigh
9、t;in t lchild,rchild,pare nt;class CHTreepublic:CHTree()ht=NULL;void In it();void huffma ncode();int select(i nt i);void Display();void can culate();void en codi ng();void decodi ng();private:HTNode* ht;int m;intn;/叶子结点数int s1;int s2;string a;/存储输入的字符串stri ng code;/存储对字符串的编码string strmax;存储叶子结点的哈夫曼编
10、码 ;l ni t()int i=1;用于记录叶子节点个数int j=0;int x=O,ru;cout a;int l=a .len gth();ht=(HTNode*)malloc(max)*sizeof(HTNode); 分配 MAXSIZE 个叶子结点的存储空间 while(xl) /统计字符出现的次数judge=1;for(j=0;ji;j+)if(htj.c=ax) 如果字符ax已经出现过,则记录,权值加 1htj.weight+;judge=0;break;if(judge)若字符没有出现过,字符入列,且权值设为 1n=i;记录叶子节点数hti .weight=1;hti.c=a
11、x;i+; x+;int CHTree:select(i nt i)/函数在ht1到hti中选择pare nt为0且weight最小的结点,并将结 点序号返回int j=1;int k=1;int s;while(htj.pare nt!=O)j+;s=j;k=j+1;while(ki)retur n s;if(htj.weighthtk.weight)htj.parent=O;如果第二次和第二次以后循环中发现有比 htj权值还小的,将htj.parent 重新设为 0j=k;始终令“ htj ”为二者中权值小的那一个htj.pare nt=-1; 如果 htj是权值较小的,将 htj的 pa
12、re nt 记为-1,k+;return s; hti.pare nt=O;hti.pare nt=O;s1= select(i-1);函数在ht1到hti-1中选择pare nt为0且weight最小的结点, 并将结hti .lchild=s1;stri.insert(O,O,O,1);Display()huffman 编码如下:n;字符t权值哈夫曼编码endl;for(i nt i=1;=n ;i+)hti.chti.weightstrica nculate()int m=0;m+=(hti.weight)*(stri.length(); 该字符所占位数为频度和每个字符 huffman码长
13、度乘积nn 内存分析: 原始编码所占内存数为8*sizeof(char)*(a.le ngth()bithuffman 编码所占内存数为me ncodi ng()for(int i=0;a.length();i+) 循环变量i用于遍历输入字符串的字符for(int j=1;j+) 循环变量j用于寻找huffman编码中与该字符的相匹配的字符编码if(ai=htj.c)code+=strj;nn 字符编码为codedecodi ng()int i=0;int m=codeen gth();nn对编码译码后所得字符:while(im)int parent=2*n-1;根结点在 HTree中的下表w
14、hile(htpare nt.rchild!=O|htpare nt.lchild!=O) 自根结点向叶子节点匹配编码,叶子节点左右孩子均为 0,此时输出字符if(codei=0)pare nt=htpare nt .l child;elsepare nt=htpare nt.rchild;htpare nt.c;void mai n()CHTree h;h.lnit(); /初始化,统计输入字符的频度,赋值各叶子节点的权重 h.huffmancode(); 建立 huffman 树h.Display();显示各字符对应的 huffman码h.e ncodi ng();对输入的字符进行编码h.decodi ng();对以上编码进行解码h.ca nculate();计算分析编码前与编码后的所占内存 system(pause);
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1