.
if (child==HTree[parent].LChild) //左孩子标‘0’ HCodeTable[i].code[k] = '0'; else HCodeTable[i].code[k] = '1' ; //右孩子标‘1’ k++; child = parent; //迭代 parent = HTree[child].parent; } HCodeTable[i].code[k] = '\\0'; Reverse(HCodeTable[i].code); //将编码字符逆置 } }
void Huffman::PrintTable() {
for (int i=0;i cout< void Huffman::Encode(char *d)//编码,d为编码后的字符串 { char *s = str; while(*s!='\\0') { for (int i=0;i void Huffman::Decode(char* s, char *d) //解码,s为编码串,d为解码后的字符串 { while(*s!='\\0') { int parent = 2*n-2; //根结点在HTree中的下标 while (HTree[parent].LChild!=-1) //如果不是叶子结点 { if (*s=='0') parent = HTree[parent].LChild; else parent = HTree[parent].RChild; . . s++; } *d = HCodeTable[parent].data; d++; } } void Huffman::Reverse(char* s)//换序 { char ch; int len = strlen(s); for (int i=0;i void Huffman::Compare(char*d)//比较压缩大小 { cout<<\编码前:\ cout<<\编码后:\ } Huffman::~ Huffman()//析构函数 { delete []HTree; delete []HCodeTable; } void main() { Huffman HFCode; char d[1024]={0}; char s[1024]={0}; cout<<\请输入要编码的字符串:\ HFCode.Init(); HFCode.CreateHTree(); HFCode.CreateCodeTable(); HFCode.Encode(d); HFCode.Decode(d,s); . 运行结果: . . int m; cout<<\欢迎使用\\n\打印哈夫曼树\\n\打印哈夫曼编码表\\n\打印编码\\n\打印解码\\n\压缩比\ while(1) {cin>>m; switch(m) { case 1: { HFCode.Print(2*HFCode.n-2,1); break; } case 2: { HFCode.PrintTable( ); break; } case 3: { cout<<\编码结果:\ break; } case 4: { cout<<\解码结果:\ break; } case 5: { HFCode.Compare(d); } } } } . . . 4. 总结 在编程时,最开始在字符统计时出现了空格无法统计的问题,后来用cin.get()函数进行统计。最后由于有一些字符没有出现过,所以还需要进行筛选。在输出哈夫曼树时 ,采用了凹入函数法进行输出,更加直观。创建编码表时 ,开始是自下到上的进行遍历,所以最后还需要进行逆序,形成最终的编码表。创建编码树的时候,没有正确运用 . . 指针的传递,结果出现了很多问题,各种存访问错误,最后经过细细地从头到尾检查,发现了是在形式参数的地方出现了错误,在获取两个最小权值的结点的时候应该用引用,改过来之后错误没有了。打印赫夫曼树是最难的部分,一开始没有找到合适的办法,出现了很多问题,最后采用凹入表示打印的方法,从最右边的结点开始一行一行的打印,最后问题也能解决了。 调试时,出现的问题是在进行编码时循环出现了错误,导致运行后编码变少,通过修改问题得以解决。 通过哈夫曼编码的程序设计,更加深入的学习了哈夫曼树编码的思想,了解了不等长编码的思想,同时也通过实践明白了编码器的原理,在编码过程中,面对出现的问题,也学习了字符串的相关函数的运用,更加了解树的存储结构,受益匪浅。 .