1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | /* 功能Function Description: 赫夫曼编码---正误待验证(调试时候感觉有地方好像出错了) 开发环境Environment: DEV C++ 4.9.9.1 技术特点Technique: 版本Version: 作者Author: 可笑痴狂 日期Date: 20120803 备注Notes: 作用: 输入大写字母组成的字符串,然后以其出现的次数为权重进行编码 */ #include<iostream> #include<cstring> #include<cstdlib> using namespace std; typedef struct Node { unsigned int weight; unsigned int parent,left,right; }HTNode,*HuffmanTree; typedef char **HuffmanCode; void HuffmanCoding( int *w, int n, char *s) { HuffmanTree HT; HuffmanCode HC; HuffmanTree p; int m,i,j,s1,s2,min1,min2,c,f,start; if (n<1) return ; m=2*n-1; HT= new HTNode[m+1]; //0号单元没用 for (p=HT+1,i=1;i<=n;++i,++p,++w) //初始化 { p->weight=*w; p->parent=0; p->left=0; p->right=0; } for (;i<=m;++i,++p) { p->weight=0; p->parent=0; p->left=0; p->right=0; } for (i=n+1;i<=m;++i) { min1=min2=0x7fffffff; //在HT[1,2,.....i-1]中选择parent为0且weight值最小的两个结点,其序号分别为s1、s2 for (j=1;j<i;++j) { if (HT[j].parent==0&&min1>HT[j].weight) { min1=HT[j].weight; s1=j; } } HT[s1].parent=i; for (j=1;j<i;++j) { if (HT[j].parent==0&&min2>HT[j].weight) { min2=HT[j].weight; s2=j; } } HT[s2].parent=i; HT[i].left=s1; HT[i].right=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; } //从叶子节点到根逆向求每个字符的赫夫曼编码 HC= new char *[n+1]; //分配n个字符编码的头指针向量 char * cd= new char [n]; //分配求编码的工作空间 cd[n-1]= '\0' ; for (i=1;i<=n;++i) //逐个字符求其编码 { start=n-1; //编码结束符标志 for (c=i,f=HT[i].parent;f;c=f,f=HT[f].parent) //从叶子到根逆向求编码 if (HT[f].left==c) cd[--start]= '0' ; else cd[--start]= '1' ; HC[i]= new char [n-start]; strcpy (HC[i],&cd[start]); } delete cd; for (i=0;i<n;++i) //输出编码 cout<<s[i]<< ": " <<HC[i+1]<<endl; } int main() { char s[1000]; int i,j; int weight[27]; /* HuffmanTree HT; HuffmanCode HC; */ cout<< "请输入字符串(大写字母):" <<endl; while (cin>>s) { memset (weight,0, sizeof (weight)); int len= strlen (s); for (i=0;i<len;++i) ++weight[s[i]- 'A' ]; for (i=0,j=0;i<26;++i) //去掉没有出现过的字母,将字母和权值都压缩存储到原来的空间中 if (weight[i]) { s[j]=i+ 'A' ; weight[j++]=weight[i]; } cout<< "赫夫曼编码为:" <<endl; HuffmanCoding(weight,j,s); cout<< "请输入字符串(大写字母):" <<endl; } return 0; } |
功不成,身已退
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步