哈夫曼编码

include <stdio.h>


define MAXBIT 100
define MAXVALUE 10000
define MAXLEAF 30//叶节点数目
define MAXNODE MAXLEAF*2-1 //节点数目


/*编码结构体*/
typedef struct
{
    int bit[MAXBIT];
    int start;
}HCodeType;


/*结点结构体*/
typedef struct
{
    int weight;
    int parent;
    int lchild;
    int rchild;
}HNodeType;


/*构造一棵哈夫曼树*/
void HuffmanTree(HNodeType HuffNode[MAXNODE], int n)
{
    int i,j,m1,m2,x1,x2;
    /*
    i、j:循环变量
    m1、m2:构造哈夫曼树不同过程中两个最小权值结点的权值
    x1、x2:构造哈夫曼树不同过程中两个最小权值结点在数组中的序号。
    */

    /*初始化存放哈夫曼树数组HuffNode[]中的结点*/
    for(i = 0; i < 2*n-1; i++)
    {
        HuffNode[i].weight = 0;
        HuffNode[i].parent = -1;
        HuffNode[i].lchild = -1;
        HuffNode[i].lchild = -1;
    }

    /*输入n个叶子结点的权值*/
    for(i = 0; i < n; i++)
    {
        printf ("Please input weight of leaf node %c:\n", 97+i);
        scanf("%d",&HuffNode[i].weight);
    }/*end for*/


    /*循环构造Huffman树*/
    for (i=0; i<n-1; i++)
    {
        m1=m2=MAXVALUE;/*m1、m2中存放两个无父结点且结点权值最小的两个结点*/
        x1=x2=0;

        /*找出所有结点中权值最小、无父结点的两个结点,并合并之为一颗二叉树*/
        for (j=0; j<n+i; j++)
        {
            if (HuffNode[j].weight<m1 && HuffNode[j].parent==-1)//比较得出所有结点中权值最小、无父结点结点,
            {
                m2=m1;//因为 m2 > m1
                x2=x1;
                m1=HuffNode[j].weight;
                x1=j;
            }
            else if (HuffNode[j].weight < m2 && HuffNode[j].parent==-1)
            {
                m2=HuffNode[j].weight;
                x2=j;
            }
        }

        /*设置找到的两个子结点x1、x2的父结点信息*/
        HuffNode[x1].parent = n+i;
        HuffNode[x2].parent = n+i;
        HuffNode[n+i].weight= HuffNode[x1].weight + HuffNode[x2].weight;
        HuffNode[n+i].lchild= x1;
        HuffNode[n+i].rchild= x2;
    }
}


int main(void)
{
    /*定义一个结点结构体数组*/
    HNodeType HuffNode[MAXNODE];

    /*定义一个编码结构体数组,同时定义一个临时变量*/
    HCodeType HuffCode[MAXLEAF],cd;

    //输入给定字符个数
    printf ("Please input n:\n");
    int n;
    scanf("%d",&n);

    /*构造一棵哈夫曼树*/
    printf("--------------------------------\n");
    HuffmanTree (HuffNode,n);

    int i,c,p;
    for (i=0; i <n; i++)
    {
        cd.start = n-1;
        c=i;
        p = HuffNode[c].parent;
        while (p!=-1)/*父结点存在*/
        {
            if(HuffNode[p].lchild ==c)
                cd.bit[cd.start]= 0;
            else
                cd.bit[cd.start]=1;

            cd.start--;/*求编码的低位*/
            c=p;
            p=HuffNode[c].parent;/*设置下一循环条件*/
        }

        /*保存求出的每个叶结点的哈夫曼编码和编码的起始位*/
        int j;
        for (j=cd.start+1; j<n; j++)
        {
            HuffCode[i].bit[j]= cd.bit[j];
        }
        HuffCode[i].start= cd.start;
    }

    /*输出已保存好的所有存在编码的哈夫曼编码*/
    printf("--------------------------------\n");
    for (i=0; i<n; i++)
    {
        printf("%c 's Huffman code is: ", 97+i);
        int j;
        for(j=HuffCode[i].start+1; j<n; j++)
        {
            printf ("%d",HuffCode[i].bit[j]);
        }
        printf ("\n");
    }
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值