哈夫曼编码与译码

问题:事情总是这样,当你明白时,很简单,但当你不会时,又好像觉得自己怎么那么笨。。。

huffman算法关键是选择两个最小的数时不要弄错了。

刚开始看时,真的很吃力,都不敢相信自己居然把huffman译码也做出来了。

代码:

#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
 
int s1,s2;
typedef struct huffmanNode
{
    int weight;
    int parent;
    int lchild;
    int rchild;
}*HuffmanTree;
 
typedef struct weight
{
    char c;
    int wt;
}*wt;
typedef char** HuffmanCode;
void select(HuffmanTree ht,int i);
void CreateHT(HuffmanTree &ht,HuffmanCode &code,wt w,int n)   //编码
{
    int m,i,j,start;
    char *cd;
    if(n<1)
    return;
    m=2*n-1;
    ht=(HuffmanTree)malloc((m)*sizeof(struct huffmanNode));
    for(i=0;i<n;i++)
    {
        ht[i].lchild=0;
        ht[i].rchild=0;
        ht[i].parent=0;
        ht[i].weight=w[i].wt;
    }
    for(j=i;j<m;j++)
    {
        ht[j].lchild=0;
        ht[j].rchild=0;
        ht[j].parent=0;
        ht[j].weight=0;
    }
    for(i=n;i<m;i++)                    //构造哈夫曼树
    {
        select(ht,i-1);
        ht[s1].parent=i;
        ht[s2].parent=i;
        ht[i].lchild=s1;
        ht[i].rchild=s2;
        ht[i].weight=ht[s1].weight+ht[s2].weight;
    }
    code=(HuffmanCode)malloc(n*sizeof(char*));
    cd=(char *)malloc(n*sizeof(char));
    for(int k=0;k<n;k++)
    {
         start=0;
         for(int p=k,f=ht[k].parent;f!=0;p=f,f=ht[f].parent)
         {
             if(ht[f].lchild==p)cd[start++]='0';
             else cd[start++]='1';
 
         }
         cd[start]='\0';
         code[k]=(char*)malloc((start)*sizeof(char));
         strcpy(code[k],cd);
          
         
    }
 
     free(cd);
}
 
void select(HuffmanTree ht,int i)
{
    int j,t,k;
    for(j=0;j<=i;j++)
    {
        if(ht[j].parent==0)
        {
            s1=j;
            break;
        }
    }
    for(t=j+1;t<=i;t++)
    {
        if(ht[t].parent==0)
        {
            s2=t;
            break;
        }
    }
    for(k=0;k<=i;k++)
    {
        if((ht[k].weight<ht[s1].weight)&&(k!=t)&&(ht[k].parent==0))
        {
            s1=k;
        }
    }
    for(k=0;k<=i;k++)
    {
        if((ht[k].weight<ht[s2].weight)&&(k!=s1)&&(ht[k].parent==0))  //容易出错,看出来了吗?
        {
            s2=k;
        }
    }
}
 
void TransHT(HuffmanTree ht,HuffmanCode code,int n,wt w)    //译码
{
    int temp;
    int len;
    int f;
    int j,m;
    for(int t=0;t<(2*n-1);t++)
    {
        if(ht[t].parent==0)
        {
            temp=t;
            break;
        }
    }
    for(j=0;j<n;j++)
    {
        len=strlen(code[j]);
        f=temp;
        for(int k=len-1;k>=0;k--)
        {
            if(code[j][k]=='0')
                f=ht[f].lchild;
            else
                f=ht[f].rchild;
        }
        for(m=0;m<n;m++)
        {
            if(ht[f].weight==w[m].wt)
            {
                cout<<code[j]<<": "<<w[m].c<<endl;
                break;
            }
        }
    }
}
int main()
{
    HuffmanTree ht;
    HuffmanCode code;
    wt w;
    int n;
    cout<<"请输入字符个数:";
    cin>>n;
    w=(wt)malloc(n*sizeof(struct weight));
    cout<<"请输入各字符的权重:"<<endl;
    for(int i=0;i<n;i++)
    {
        cin>>w[i].c>>w[i].wt;
    }
    cout<<"创建哈夫曼树:"<<endl;
    CreateHT(ht,code,w,n);
    cout<<"输出哈夫曼编码:"<<endl;
    for(int i=0;i<n;i++)
    {
        cout<<w[i].c<<"  ";
        cout<<code[i];
        cout<<endl;
    }
    cout<<"译码结果为:"<<endl;
    TransHT(ht,code,n,w);
    return 0;
}

运行结果:

 

posted @   xshang  阅读(810)  评论(2编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示