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


     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='';   //定义当前结点的字符,初始化为''
     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 }

    测试结果:

  • 相关阅读:
    机器学习常用算法
    判别式模型与生成式模型
    数据清洗方法
    机器学习项目流程清单
    免费的论文查重网站
    (转载)python应用svm算法过程
    opencv图像阈值设置的三种方法
    Tensorflow读取csv文件(转)
    tensorflow的数据输入
    为什么有些图像在显示前要除以255?(zhuan)
  • 原文地址:https://www.cnblogs.com/ISGuXing/p/9075309.html
Copyright © 2020-2023  润新知