C++Huffman树的构造实现及编码译码过程

本文介绍了一种基于哈夫曼树的编码方法实现过程,包括哈夫曼树的构建及编码、解码操作。通过定义节点结构和一系列算法步骤,实现了对特定字符串的有效压缩与还原。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct 
{
    int *code;
    char str;
}Num;
typedef struct  
{
    int  weight,parent,left,right;
    bool Selected;  ///是否已经选过该节点,两个节点构建父节点时,选过的节点就不能再选了
    Num  ch;
}HNode,*pHNode;
const int n=5;
pHNode HTREE=NULL;
////哈夫曼树初始化,转载n个字符和相应的权值,并申请n-1个辅助节点用于构建Huffman树
void InitHtree(pHNode &htree,int n)
{
    htree=(pHNode)malloc((2*n-1)*sizeof(HNode));
    char str[]="abcde";
    int weight[]={4,8,1,2,11};
    for (int i=0;i<n;i++)
    {
        htree[i].weight=weight[i];
        htree[i].left=-1;
        htree[i].right=-1;
        htree[i].ch.str=str[i];
        htree[i].Selected=false;
    }
}
////选取两个较小的节点,返回节点的序号
void SelectTwoMinNode(pHNode htree,int len,int &n1,int &n2)
{
    int min1,min2;
    int i,j;
    for (i=0;i<len;i++)
    {
        if (htree[i].Selected==false)
        {
            min1=i;
        }
    }
    for (j=0;j<len;j++)
    {
        if (htree[j].Selected==false&&j!=i-1)
        {
            min2=j;
        }
    }
    if (htree[min1].weight>htree[min2].weight)
    {
        int temp=min1;
        min1=min2;
        min2=temp;
    }
    for (i=0;i<len;i++)
    {
        if (htree[i].Selected==false)
        {
            if (htree[i].weight<htree[min1].weight)
            {
                min2=min1;
                min1=i;
            }
            else if(htree[i].weight<htree[min2].weight&&htree[i].weight>htree[min1].weight)
                min2=i;
        }

    }
    htree[min1].Selected=true;///标志已选取
    htree[min2].Selected=true;
    n1=min1;
    n2=min2;
}
//////HuffmanTree讲的是如何编码,即构建字符和编码之间的对应关系
void HuffmanTree(pHNode &htree,int n)////htree是一个节点数组,n为字符个数
{
    int m=2*n-1,n1,n2;
    int i,child,parent;
    int *path=(int *)malloc(m*sizeof(int));
    for (i=n;i<m;i++)
    {
        SelectTwoMinNode(htree,i,n1,n2);
        htree[i].left=n1;
        htree[i].right=n2;
        htree[n1].parent=htree[n2].parent=i;
        htree[i].weight=htree[n1].weight+htree[n2].weight;
        htree[i].Selected=false;
    }
    htree[--i].parent=-1;//根节点的标志
    for (i=0;i<n;i++)
    {
        for (child=i,parent=htree[child].parent,m=0;parent!=-1;m++)
        {
            if (htree[parent].left==child)///孩子位于双亲的左边
                   path[m]=0; 
            else                          ///孩子位于双亲的右边
                   path[m]=1;

            child=parent;
            parent=htree[child].parent;
        }
        htree[i].ch.code=(int *)malloc(n*sizeof(int));
        int k;
        int len=m;
        for (k=0;k<len;k++)     /////倒序过来
              htree[i].ch.code[k]=path[--m];
        htree[i].ch.code[k]='\n';
    }
    delete[]path;

}
/////HuffmanCoding按照huffmantree对字符串编码
int *HuffmanCoding(pHNode htree,char * source)
{
       int* encoding=new int[100];
       int* p;
       int len=strlen(source);
       int pos;
       int j=0;
       for(int i=0;i<len;i++)
       { 
           pos=*source++-'a';
           p=htree[pos].ch.code;
           while(*p!='\n')
               encoding[j++]=*p++;
        }
       encoding[j]='\n';
       return encoding;
}
/////对编码进行译码,还原字符
void HuffmanDecoding(pHNode htree,int m,int *buff)/////htree是一个节点数组,m为hree节点个数,buff字符串
{
     int p=m-1;
     while (*buff!='\n')
     {
         if (*buff==0)
             p=htree[p].left;
         else
             p=htree[p].right;
         buff++;
         if (htree[p].left==-1&&htree[p].right==-1)
         {
             printf("%c",htree[p].ch.str);
             p=m-1;
         }
     }
}

int main()
{
    InitHtree(HTREE,n);
    HuffmanTree(HTREE,n);
    char *str="abcbcaedd";
    int *result=HuffmanCoding(HTREE,str);
    HuffmanDecoding(HTREE,2*n-1,result);
    system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值