哈夫曼树表

来源:互联网 发布:java打包成jar包 编译 编辑:程序博客网 时间:2024/06/05 15:47
//利用二叉树结构实现赫夫曼编 / 解码器。//基本要求://1、 初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立赫夫曼树//2、 建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将每个字符的编码输出。//3、 编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。//4、 译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译码,并输出译码结果。//5、 打印(Print):以直观的方式打印赫夫曼树(选作)//6、 计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼编码的压缩效果。////测试数据://I love data Structure, I love Computer。I will try my best to study data Structure.//提示://1、用户界面可以设计为“菜单”方式:能够进行交互。//2、根据输入的字符串中每个字符出现的次数统计频度,对没有出现的//字符一律不用编码。#include #include //包含栈类#include using namespace std;void Init(char *s, int a[],char c[],int *n){char *p = s;int j = 0;int b[128] = { 0 };while (*p != NULL){b[(int)*p]++;p++;}for (int i = 0; i <= 128; i++){if (b[i] != 0) { a[j] = b[i]; c[j] = (char)i; j++; }}c[j - 1] = '\0';* n = j-1;}void reverse(char c[]){int i = strlen(c);char temp;for (int j = 0; j < i/2; j++){temp = c[j];c[j] = c[i-1 - j];c[i-1 - j] = temp;}}struct HNode{int weight;int parent;int LChild;int RChild;};struct HCode{char data;int weight;char code[100];};void selectMin(int *x,int *y,HNode HTree[] ,int i){int n=0;while ((n < i) && HTree[n].parent != -1){n++;}int min=n;for (int j = 0; j <= i; j++){if (HTree[j].parent == -1 && HTree[j].weight <=HTree[min].weight) min = j;}*x = min;n = 0;while ((n < i)&& ((HTree[n].parent != -1) || n == *x)){n++;}min = n;for (int j = 0; j <= i; j++){if (HTree[j].parent == -1 && HTree[j].weight <= HTree[min].weight&&j!=*x) min = j;}*y = min;if (*x>*y){n = *x;*x = *y;*y = n;}}class Huffman{private:HNode * HTree;HCode * HCodeTable;public:Huffman(){};void CreateHTree(int a[], int n);void CreateCodeTable(char c[], int n);void Encode(char * s, char * d, int n);void Decode(char * s, char * d, int n);};void Huffman::CreateHTree(int a[], int n){HTree = new HNode[2 * n + 1];for (int i = 0; i < n; i++){HTree[i].weight = a[i];HTree[i].LChild = -1;HTree[i].RChild = -1;HTree[i].parent = -1;}int x, y;for (int i = n; i < 2 * n-1; i++){selectMin(&x, &y, HTree, i);HTree[x].parent = HTree[y].parent = i;HTree[i].weight = HTree[x].weight + HTree[y].weight;HTree[i].LChild = x;HTree[i].RChild = y;HTree[i].parent = -1;}}void Huffman::CreateCodeTable(char c[], int n){HCodeTable = new HCode[n];for (int i = 0; i < n; i++){HCodeTable[i].data = c[i];int child = i;int parent = HTree[i].parent;int k = 0;while (parent != -1){if (child == HTree[parent].LChild) HCodeTable[i].code[k] = '0';else HCodeTable[i].code[k] = '1';k++;child = parent;parent = HTree[child].parent;}HCodeTable[i].code[k] = '\0';reverse(HCodeTable[i].code);}}void Huffman::Encode(char * s, char * d,int n){for (unsigned int i = 0; i <= strlen(s) - 1; i++){for (int j = 0; j<=n-1; j++){if (HCodeTable[j].data == s[i]){for (unsigned int k = 0; k <= strlen(HCodeTable[j].code) - 1; k++){*d = HCodeTable[j].code[k];d++;}}}}*d = '\0';}void Huffman::Decode(char * s, char *d,int n){while (* s!='\0'){//cout << *s;int parent = 2 * n - 1 - 1;while (HTree[parent].LChild != -1){if (*s == '0')parent = HTree[parent].LChild;elseparent = HTree[parent].RChild;s++;}*d = HCodeTable[parent].data;//cout << *d;d++;}*d = '\0';}int main(){char s[1024] = "I love data Structure, I love Computer.I will try my best to study data Structure.";char d[1024];char e[1024];char c[128];int a[128] = { 0 };int n;cout << "****************************测试*****************************" << endl;cout<< "编码前字符串:" << endl;cout << s<<endl;Init(s,a,c,&n);Huffman tree;tree.CreateHTree(a, n);//tree.Print(2*n-2);cout << endl;tree.CreateCodeTable(c, n); tree.Encode(s, d, n);cout << "编码后:"<<d<<endl;tree.Decode(d, e, n);cout << "解码:" << e << endl;double rate = ((double)strlen(d) / (((double)strlen(e)) * (double)8));cout << "压缩比例:" << rate<< endl;cout << "***************************测试结束*************************" << endl;cout << "请输入字符串:" << endl;memset(s, 0, sizeof(s));cin.get(s,1024);Init(s, a, c, &n);tree.CreateHTree(a, n);tree.CreateCodeTable(c, n);tree.Encode(s, d, n);cout << "编码后:" << d << endl;tree.Decode(d, e, n);cout << "解码:" << e << endl;rate = ((double)strlen(d) / (((double)strlen(e)) * (double)8));cout << "压缩比例:" << rate << endl;cout << "*************************感谢使用****************************" << endl;return 0;}
0 0
原创粉丝点击