哈夫曼编码

描述
写一个哈夫曼码的编/译码系统,要求能对要传输的报文进行编码和解码。构造哈夫曼树时,权值小的放左子树,权值大的放右子树,编码时右子树编码为1,左子树编码为0.
 
 
输入
输入表示字符集大小为n(n <= 100)的正整数,以及n个字符和n个权值(正整数,值越大表示该字符出现的概率越大);
输入串长小于或等于100的目标报文。
 
输出
经过编码后的二进制码,占一行;
以及对应解码后的报文,占一行;
最后输出一个回车符。
 
输入样例
5 a b c d e 12 40 15 8 25
bbbaddeccbbb
输出样例
00011111110111010110110000
bbbaddeccbbb

 
#include
#include
#include

struct node
{
    char zifu;
    int wet,par,lch,rch;
};

struct code
{
    char data;
    char cod[20];
};

typedef struct hftree
{
    struct node ht[100];
    int root;
}hftree,*phftree;


phftree create(int n,int w[],char f[])
{
    phftree pht;
    int i,j,x1=1,x2=1; //最小权值其对应的下标
    int m1=10000,m2=10000;  // 记录最小的权值
    pht=(phftree)malloc(sizeof(hftree));
    for(i=1;i<=2*n-1;i++)  //n个数,即有n个叶子节点,生成的哈夫曼树有2n-1 个节点
    {
        pht->ht[i].par=0;
        pht->ht[i].lch=0;
        pht->ht[i].rch=0;
        if(i<=n)
        {
            pht->ht[i].wet=w[i-1];
            pht->ht[i].zifu=f[i-1];
        }
        else pht->ht[i].wet=0;
    }
    for(i=1;iht[j].wetht[j].par==0)
        {
            m2=m1;
            x2=x1;
            m1=pht->ht[j].wet;
            x1=j;
        }
        else if(pht->ht[j].wetht[j].par==0)
        {
            m2=pht->ht[j].wet;
            x2=j;
        }
    }
        pht->ht[x1].par=n+i;
        pht->ht[x2].par=n+i;
        pht->ht[n+i].lch=x1;
        pht->ht[n+i].rch=x2;
        pht->ht[n+i].wet=pht->ht[x1].wet+pht->ht[x2].wet;
        pht->root=n+i;
        m1=10000;m2=10000;
    }
    return pht;
}


void coding(phftree pht,struct code HC[],int root)
{
     static int codelen=0,i=1;  // 这里用静态  很重要,因为要进行递归
     static char cd[100];
    if (pht->ht[root].rch == 0)	{
		cd[codelen] = '\0';  //  字符串结尾的标志是'\0'
		HC[i].data=pht->ht[root].zifu;
		strcpy(HC[i++].cod, cd);

	}
	else {
		cd[codelen++] = '0';
		coding (pht, HC, pht->ht[root].lch);
		codelen--;  // 将‘\0’去掉
		cd[codelen++]  =  '1';
		coding (pht, HC, pht->ht[root].rch);
		codelen--; // 将‘\0’去掉
	}

}

int main()
{
    phftree pht;
    struct code HC[30];
    int i,j,n,len,w[30]={0};
    char f1[60]={'\0'},f[30]={'\0'};
    char file[100]={'\0'};
    char transf1[100][20]={'\0'},transf2[100]={'\0'};
    scanf("%d",&n);
    for(i=0;i<2*n;i++)scanf("%c",&f1[i]);
    for(i=0;iroot);  // 根据哈夫曼树 对字符进行编码
    for(i=0;file[i]!='\0';i++)  // 这里主要是对输入的字符进行编码,根据coding函数得出的编码情况
    {
        for(j=1;j<=n;j++)
        {
            if(file[i]==HC[j].data)  // 与哪个字符相等,就把字符对应的哈夫曼编码赋值给它
            {
                strcpy(transf1[i],HC[j].cod);
                break;
            }
        }
    }


    len=strlen(file);
    for(i=0;i
这里有一些非常优秀的博客也可以进行参考理解
哈夫曼编码

你可能感兴趣的:(C)