C++实现哈夫曼树与哈夫曼编码

11 篇文章 10 订阅
5 篇文章 1 订阅

哈夫曼树的存储表示

typedef char ElemType;
typedef struct
{
    ElemType data;              //结点存的数据
    int weight;                 //结点的权值
    int parent,lchild,rchild;   //结点的双亲、左孩子、右孩子的下标
} HTNode,*HuffmanTree;          //动态分配数组存储哈夫曼树

构造哈夫曼树

void CreateHuffmanTree(HuffmanTree &HT,int n)
{
    //构造哈夫曼树HT
    if(n<=1)
    {
        cout<<"HuffmanTree节点数输入错误!"<<endl;
        return;
    }
    int m=2*n-1;
    int s1=1,s2=1;
    HT=new HTNode[m+1];         //0号单元未用,所以需要动态分配m+1个单元,HT[m]表示根结点
    for(int i=1; i<=m; ++i)     //将1~m号单元中的双亲、左孩子、右孩子的下标都初始化为0
    {
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0;
    }
    for(int i=1; i<=n; ++i)     //输入前n个单元中叶子结点的权值(包括空格)
    {

        cout<<"请输入第"<<i<<"个叶子结点的数据(字符):"<<endl;
        char c;//用来保存之前键入的回车键
        c=cin.get();
        HT[i].data=cin.get();
        cout<<"请输入第"<<i<<"个叶子结点的权值:"<<endl;
        cin>>HT[i].weight;
    }
    //--------------------------初始化工作结束,下面开始创建完整哈夫曼树
    for(int i=n+1; i<=m; ++i)
    {
        //通过n-1次的选择、删除、合并来创建哈夫曼树
        Select(HT,i-1,s1,s2);                       //在HT[k](1<=k<=i-1)中选择两个其双亲域为0且权值最小的结点,并返回它们在HT中的序号s1和s2
        HT[s1].parent=i;
        HT[s2].parent=i;            //得到新结点i,从森林中删除s1,s2,将s1和s2的双亲域由0改为i
        HT[i].lchild=s1;
        HT[i].rchild=s2;            //s1,s2分别作为i的左右孩子
        HT[i].weight=HT[s1].weight+HT[s2].weight;   //i的权值为左右孩子权值之和
    }
}

哈夫曼编码的存储表示

typedef char **HuffmanCode;//动态分配数组存储哈夫曼编码表

根据哈夫曼树求哈夫曼编码表

void CreateHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int &n)
{
    //从叶子到根逆向求每个字符的哈夫曼编码,存储在编码表HC中
    HC=new char*[n+1];      //分配存储n个字符编码的编码表动态空间
    char *cd=new char[n];    //分配临时存放每个字符编码的动态数组空间
    cd[n-1]='\0';           //(末尾)编码结束符
    for(int i=1; i<=n; i++) //逐个字符求哈夫曼编码
    {
        int start=n-1;      //start开始时指向最后,即编码结束符位置
        int c=i,f=HT[i].parent;//f指向结点c的双亲结点
        while(f!=0)         //从叶子结点开始向上回溯,直到根结点
        {![在这里插入图片描述](https://img-blog.csdnimg.cn/20190602094744711.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNjY0NDQ3,size_16,color_FFFFFF,t_70)
            --start;
            if(HT[f].lchild==c) cd[start]='0';//结点c是f的左孩子,则生成代码0
            else cd[start]='1';               //结点c是f的右孩子,则生成代码1
            c=f;
            f=HT[f].parent;               //继续向上回溯
        }                   //求出第i个字符的编码(结点为c,双亲为f;之后结点为f,双亲为HT[f].parent)
        HC[i]=new char[n-start];              //为第i个字符编码分配空间
        strcpy(HC[i],&cd[start]);             //将求得的编码从临时空间cd复制到HC的当前行中(导入:#include<cstring>)
    }                       //for
    delete cd;              //释放临时空间
}

运行截图

(输入a-z以及空格为哈夫曼树的数据,求出对应的哈夫曼编码表,实现英文以及对应的哈夫曼编码的相互转换)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
完整源代码下载地址:https://download.csdn.net/download/qq_41664447/11221762

  • 23
    点赞
  • 182
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值