数组实现哈夫曼树及哈夫曼编码

本文详细介绍了一种使用数组实现哈夫曼树及其编码的方法。文章首先定义了哈夫曼树的数据结构,并通过具体示例展示了如何根据字符及其权重构建哈夫曼树。接着介绍了如何为树中的每个字符分配唯一的二进制编码。最后,提供了完整的C语言代码实现。

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

百度百科介绍:http://baike.baidu.com/link?url=DDUm7qBwh4XVGlhskrXjpQZx6mu74iy-54mkIBMUIME8o22OKvbi61yHxOz0Ljm5YekqESS70n3rTKSHqPu3Z_

简单的图示介绍:

用数组实现的哈夫曼树及哈夫曼编码:
 
#include <cstdio>
#define N 5
#define M 2 * N - 1
#define MaxInt 666666
//建成的哈夫曼树存放在HTree数组中
//且通过数组元素下标来确定父节点,左节点,右节点
struct
{
    int weight; //权
    int left;   //左节点
    int right;  //右节点
    int parent; //父节点
} HTree[M];

//对一篇文章编码,我们假设已经得到了每个字符(c)及它们的出现权重(weight)
struct
{
    char c;
    int weight;
    int bit[100];  //存储每个字符编码的逆序
    int code[100]; //存储每个字符的编码
    int len;       //存储每个字符的编码的长度
} cc[N] = {{'a', 1, {0}, {0}, 0}, {'b', 2, {0}, {0}, 0}, {'c', 3, {0}, {0}, 0}, {'d', 4, {0}, {0}, 0}, {'e', 5, {0}, {0}, 0}};

//初始化成森林
void InitHTree()
{
    int i;
    for (i = 0; i < M; i++)
    {
        if (i < N)
            HTree[i].weight = cc[i].weight;
        else
            HTree[i].weight = 0;
        HTree[i].left = HTree[i].right = HTree[i].parent = -1; //数组元素以0为第一元素,故将其初始化为-1
    }
}

//建哈夫曼树
void BuidHTree()
{
    int i, j, x, y;
    int min;
    for (i = 0; i < N - 1; i++)
    {
        min = MaxInt;
        //找最小的两个元素x,y
        for (j = 0; j < M; j++)
        {
            if (HTree[j].parent == -1 && HTree[j].weight > 0 && min > HTree[j].weight)
            {
                min = HTree[j].weight;
                x = j;
            }
        }
        min = MaxInt;
        for (j = 0; j < M; j++)
        {
            if (HTree[j].parent == -1 && HTree[j].weight > 0 && j != x && min > HTree[j].weight)
            {
                min = HTree[j].weight;
                y = j;
            }
        }
        HTree[x].parent = HTree[y].parent = i + N; //父节点为HTree[i+N]
        HTree[i + N].left = x;
        HTree[i + N].right = y;
        HTree[i + N].weight = HTree[x].weight + HTree[y].weight;
    }
}

//哈夫曼编码:每一个字符都得到一个二进制编码
void HuffCode()
{
    int i, j;
    int pos, child, parent;
    for (i = 0; i < N; i++)
    {
        pos = 0;
        child = i;
        parent = HTree[i].parent;
        while (parent != -1)
        {
            if (HTree[parent].left == child)
                cc[i].bit[pos] = 0;
            else
                cc[i].bit[pos] = 1;
            pos++;
            child = parent;
            parent = HTree[parent].parent;
        }
        cc[i].len = pos;

        //将逆序的结果存到正序中
        pos--;
        for (j = 0; j < cc[i].len; j++, pos--)
            cc[i].code[j] = cc[i].bit[pos];
    }
}
int main()
{
    int i, j;
    //初始化森林
    InitHTree();
    //建哈夫曼树
    BuidHTree();
    //测试建树结果
    for (i = 0; i < M; i++)
        printf("%d ", HTree[i].weight);
    printf("\n");
    //哈夫曼编码
    HuffCode();
    //测试编码结果:每一个字符都得到一个特定的二进制编码
    for (i = 0; i < N; i++)
    {
        printf("%c:", cc[i].c);
        for (j = 0; j < cc[i].len; j++)
            printf("%d ", cc[i].code[j]);
        printf("\n");
    }
    return 0;
}
原文地址: http://blog.hewie.cn/article/1921070716
 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hober.z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值