哈夫曼编码实现(链式实现)

 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 }

 

测试结果:

 

 

posted @ 2018-05-23 09:33  ISGuXing  阅读(910)  评论(0编辑  收藏  举报