1 #include<iostream>
2 #include<stdlib.h>
3 #include<string.h>
4 #define INF 10000000 //定义INF为无穷大
5 using namespace std;
6 struct Node{
7 char data='\0'; //定义当前结点的字符,初始化为'\0'
8 int value=0; //定义结点的权值,初始化为 0
9 string code=""; //存储哈夫曼编码,初始化为空字符串
10 Node *lchild,*rchild,*parents; //定义左右子结点、双亲结点
11 };
12 Node * insert_huffman_tree(Node *root,Node *lchild,Node *rchild){ //哈夫曼树的插入函数
13 root->lchild=lchild;
14 root->rchild=rchild;
15 return root; //返回根结点
16 }
17 void get_huffman_code(Node *root){ //获取哈夫曼编码函数
18 if(root->lchild==NULL&&root->rchild==NULL){ //说明是叶子结点
19 cout<<"字符 "<<root->data<<" 的哈夫曼编码为: "<<root->code<<endl; //输出当前字符的哈夫曼编码
20 return ; //结束递归
21 }
22 root->lchild->code=(root->code)+"0"; //左子结点为 0
23 get_huffman_code(root->lchild); //递归左子树
24 root->rchild->code=(root->code)+"1"; //右子结点为 1
25 get_huffman_code(root->rchild); //递归右子树
26 return ; //结束递归
27 }
28 int main(){
29 Node *root;
30 cout<<"下一行输入一串仅包含小写字母的字符串:"<<endl;
31 char s[100]; //定义长度为100的字符串 S
32 cin>>s; //输入字符串 S
33 Node num[51]; //因为字符串S最多包含26个小写字母,所以整个哈夫曼树的结点最多为51个
34 for(int i=0;i<51;i++){
35 num[i].lchild=num[i].rchild=num[i].parents=NULL; //初始化树结点的左右子结点、双亲结点
36 }
37 int vis[200]; //定义标记数组
38 memset(vis,0,sizeof(vis)); //初始化标记数组
39 int t=0; //用 t 来记录当前有多少个树结点
40 for(int i=0;i<strlen(s);i++){
41 if(num[s[i]-'a'].value==0) t++; //统计多少个不同的字符
42 num[s[i]-'a'].data=s[i];
43 num[s[i]-'a'].value++; //统计s[i]字符出现的次数,即s[i]字符的权值
44 }
45 for(int i=0;i<25;i++){ //因为小写字母只有26个,因此最多找25次,所以循环只需要最多25次即可
46 int min_value1=INF; //初始化权值无穷大
47 int min_value2=INF; //初始化权值无穷大
48 int x,y; //x,y表示最小值和次小值
49 x=y=-1; //初始化x,y
50 for(int j=0;j<51;j++){ //最多遍历51个结点,寻找最小值和次小值
51 if(min_value1>num[j].value&&!vis[j]&&num[j].value!=0){
52 y=x;
53 min_value2=min_value1;
54 x=j;
55 min_value1=num[j].value;
56 }else if(min_value2>num[j].value&&!vis[j]&&num[j].value!=0){
57 y=j;
58 min_value2=num[j].value;
59 }
60 }
61 if(y==-1) break; //说明只剩下一个结点了,可以跳出循环
62 num[t++].value=num[x].value+num[y].value;
63 vis[x]=vis[y]=1; //标记已经加入哈夫曼树的树结点
64 root=insert_huffman_tree(&num[t-1],&num[x],&num[y]); //将树结点插入哈夫曼树
65 }
66 cout<<"输入的字符串的各个字符的哈夫曼编码是:"<<endl;
67 get_huffman_code(root); //获取并打印字符的哈夫曼编码
68 return 0;
69 }
测试结果: