赫夫曼树与赫夫曼编码

赫夫曼树,又称最优二叉树。它的最优体现在每个结点的权值与它的路径长度的乘积之和最小。具体定义参考博客: https://blog.csdn.net/heart_love/article/details/50901943
赫夫曼树的构造原理非常简单,每次在当前的树中找到节点权值最小的两个节点分别作为左右子树,他们双亲的权值就是这两个左右孩子的权值之和。循环构造,直到生成一棵树。
赫夫曼编码就是在赫夫曼树的基础上,左边编码为0,右边为1,构成的二进制码值。
#include <stdio.h>
#include <string.h>

#define MAXVALUE      10000

typedef struct
{
    char data;
    int weight;
    int parent;
    int lchild;
    int rchild;
    int flag;
}HuffNode;

typedef struct
{
    char code[10];
    int start;
}HuffCode;

HuffNode H[9];
HuffCode HC[5];                            //当有n个结点需要构造赫夫曼树时,总共需要2*n-1个节点

int select (HuffNode *H, int n)           //选出当前树中的最小值
{
    int min = MAXVALUE, i, j;
    for(i = 0; i <= n; i++)
    {
        if(H[i].weight < min && H[i].flag == -1)
        {
            min = H[i].weight;
            j = i;
        }
    }
    H[j].flag = 1;
    return j;
}

void HuffTreeInit (HuffNode *H, int n)
{
    int i;
    for(i = 0; i < n; i++)
    {
        H[i].data = getchar();
        scanf("%d", &(H[i].weight));
        getchar();
        H[i].flag = -1;
        H[i].lchild = -1;
        H[i].parent = -1;
        H[i].rchild = -1;
    }
    for(; i < 2*n-1; i++)
    {
        H[i].flag = -1;
        H[i].lchild = -1;
        H[i].parent = -1;
        H[i].rchild = -1;
    }
}

void CreatHuffTree (HuffNode *H, int n)
{
    int i, l, r;
    for(i = n; i < 2*n-1; i++)
    {
        l = select(H, i-1);                     //分别选出当前树中的最小的俩个权值,构造成二叉树
        r = select(H, i-1);
        H[l].parent = i;
        H[r].parent = i;
        H[i].weight = H[l].weight+H[r].weight;
        H[i].lchild = l;
        H[i].rchild = r;
    }
}

void PrintHuffTree (HuffNode *H, int n)         //将构造好的赫夫曼树(最优二叉树)层序遍历
{
    HuffNode list[2*n-1];
    int in, out;
    in = out = 0;
    list[in++] = H[2*n-2];
    while(in > out)
    {
        printf("%d\n", list[out].weight);
        if(list[out].lchild != -1)
        {
            list[in++] = H[list[out].lchild];
            list[in++] = H[list[out].rchild];

        }
        out++;
    }
}

void CreatHuffCode (HuffNode *H, HuffCode *HC, int n)    //赫夫曼编码,从每个节点开始,向上编码
{
    int i, c, f;
    HuffCode d;
    for(i = 0; i < n; i++)
    {
        d.start = n+1;
        c = i;
        f = H[c].parent;
        while(f != -1)                                    //一直编码,知道结点为根节点
        {
            if(H[f].lchild == c)
            {
                d.code[--d.start] = '0';
            }
            else
            {
                d.code[--d.start] = '1';
            }
            c = f;
            f = H[c].parent;
        }
        HC[i] = d;
    }
}

void PrintHuffCode (HuffNode *H, HuffCode *HC, int n)
{
    int i, j;
    for(i = 0; i < n; i++)
    {
        printf("data:%c   ", H[i].data);
        for(j = HC[i].start; j < n+1; j++)
        {
            printf("%c", HC[i].code[j]);
        }
        printf("\n");
    }
}

int main ()
{
    HuffTreeInit(H, 5);
    CreatHuffTree(H, 5);
    CreatHuffCode (H, HC, 5) ;
    PrintHuffCode(H, HC, 5);
//    PrintHuffTree(H, 5);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值