哈夫曼编码

1)数组实现哈夫曼编码-中间编码

这里写图片描述

这里写图片描述

int main(void)
{
    HuffNode * F;
    int n;
    printf("输入叶子结点个数");
    scanf("%d",&n);
    //创建森林
    F=(HuffNode *)malloc((2*n-1)*sizeof(HuffNode));
    for(int i=0;i<n;i++)
    {
        //fflush(stdin);不建议使用
        setbuf(stdin,NULL);//推荐
        printf("输入字母:");
        scanf("%c",&(F[i].word));

        printf("输入字母的数目:");
        scanf("%d",&(F[i].weight));

        F[i].left=F[i].right=F[i].parent=-1;
        F[i].code=NULL;

    }
    //创建HuffmanTree
    CreateHuffmanTree(F,n);

    for(int j=0;j<2*n-1;j++)
    {
        printf("%c,%d,%d,%d,%d\n",F[j].word,F[j].weight,F[j].left,F[j].right,F[j].parent);
    }
    //创建HuffmanCode
    CreateHuffmanCode(F,n);

    //遍历HuffmanCode
    PrintHuffmanCode(F,n);

    return 0;
}
#include<stdio.h>
#include<stdlib.h>
typedef struct{
    char word;//字母
    int weight;//个数
    int left,right,parent;//左右子女,及子女
    int *code;
}HuffNode;
//创建HuffmanTree
void CreateHuffmanTree(HuffNode * F,int n)
{
    int loop,k1,k2,i;//loop创建树需要遍历n-1for(loop=0;loop<n-1;loop++)
    {
        for(k1=0;k1<n+loop && F[k1].parent!=-1;k1++);//k1表示最小值
        for(k2=k1+1;k2<n+loop && F[k2].parent!=-1;k2++);//k2表示次小值
        //找最小和次小
        for(i=k2;i<n+loop;i++)
        {
            if(F[i].parent==-1)
            {
                if(F[i].weight < F[k1].weight)
                {
                    k2=k1;
                    k1=i;
                }
                else if(F[i].weight < F[k2].weight)
                    k2=i;
            }
        }
        //添加结点来连接
        F[k1].parent=i;
        F[k2].parent=i;

        F[i].word='x';
        F[i].weight=F[k1].weight+F[k2].weight;
        F[i].left=k1;
        F[i].right=k2;
        F[i].parent=-1;
        F[i].code=NULL;
    }

}
//创建HuffmanCode
void CreateHuffmanCode(HuffNode * F,int n)
{
    int *p;
    int i,c,pa;
    for(i=0;i<n;i++)
    {

        F[i].code=p=(int *)malloc(n*sizeof(int));//直接对F[i].code操作,简化代码
        p[0]=0;
        c=i;
        while(F[c].parent!=-1)
        {
            pa=F[c].parent;
            //在左边为
            if(F[pa].left==c)
                p[++(p[0])]=0;
            else
                p[++(p[0])]=1;
            c=pa;
        }
    }
}
//遍历HuffmanCode
void PrintHuffmanCode(HuffNode *F,int n)
{
    for(int i=0;i<n;i++)
    {
        printf("字母%c哈夫曼编码:",F[i].word);
        //需要从根开始往下输出
        for(int j=F[i].code[0];j>0;j--)
            printf("%2d",F[i].code[j]);
        printf("\n");
    }
}

2)链表实现哈夫曼编码-中间编码

这里写图片描述

这里写图片描述

这里写图片描述



#include<stdio.h>
#include<stdlib.h>
typedef struct node{
    char word;//字母
    int weight;//个数
    struct node *left,*right;
}HuffNode;
int main(void)
{
    HuffNode ** F;//存叶子结点
    HuffNode * root;//哈夫曼树根
    int i;
    int n;
    printf("输入叶子结点个数");
    scanf("%d",&n);
    //创建森林
    F=(HuffNode**)malloc(n*sizeof(HuffNode*));
    for(i=0;i<n;i++)
    {
        F[i]=(HuffNode*)malloc(sizeof(HuffNode));
        F[i]->left=F[i]->right=NULL;
        setbuf(stdin,NULL);
        printf("输入字母");
        scanf("%c",&F[i]->word);
        printf("输入字母数量");
        scanf("%d",&F[i]->weight);
    }
    //创建哈夫曼树
    root=CreateHuffmanTree(F,n);
    //输出哈夫曼树
    PrintHuffmanTree(root);
    return 0;
}
//创建HuffmanTree
HuffNode * CreateHuffmanTree(HuffNode ** F,int n)
{   
    HuffNode *p;
    int k1,k2,i;

    //需要遍历n-1
    for(int loop=1;loop<n;loop++)
    {
        for(k1=0;k1<n && !F[k1];k1++);//找到没有双亲遍历的结点
        for(k2=k1+1;k2<n && !F[k2];k2++);
        //找最小和次小
        for(i=k2;i<n;i++)
        {
            if(F[i])
            {
                if(F[i]->weight < F[k1]->weight)
                {
                    k2=k1;
                    k1=i;
                }
                else if(F[i]->weight < F[k2]->weight)
                    k2=i;
            }
        }
        //创建双亲结点连接叶子结点
        p=(HuffNode*)malloc(sizeof(HuffNode));
        p->left=F[k1];
        p->right=F[k2];
        p->weight=F[k1]->weight+F[k2]->weight;
        p->word='x';

        F[k1]=p;//新生成的树放回
        F[k2]=NULL;
    }

    return F[k1];
}
//输出哈夫曼树
void PrintHuffmanTree(HuffNode * root)
{
    if(root)
    {
        printf("%5c",root->word);
        PrintHuffmanTree(root->left);
        PrintHuffmanTree(root->right);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值