哈夫曼编码C语言

这篇博客介绍如何使用C语言构建哈夫曼树并为叶节点生成哈夫曼编码。通过设置结构数组huffnode来存储哈夫曼树节点信息,并利用结构数组huffcode保存各字符的哈夫曼编码。文章详细解释了构建哈夫曼树的过程以及如何从叶节点回溯到根节点获取编码。
摘要由CSDN通过智能技术生成
 

参考:《软件设计师考试——考点分析与真题详解》

      我们设置一个结构数组 huffnode 保存哈夫曼树中各结点的信息。根据二叉树的性质可知,具有n个叶子结点的哈夫曼树共有 2n-1 个结点,所以数组 huffnode 的大小设置为 2n-1 。huffnode 结构中有 weight, lchild, rchild 和 parent 域。其中,weight 域保存结点的权值, lchild 和 rchild 分别保存该结点的左、右孩子的结点在数组 huffnode 中的序号,从而建立起结点之间的关系。为了判定一个结点是否已加入到要建立的哈夫曼树中,可通过 parent 域的值来确定。初始时 parent 的值为 -1。当结点加入到树中去时,该结点 parent 的值为其父结点在数组 huffnode 中的序号,而不会是 -1 了。

      求叶结点的编码:

  该过程实质上就是在已建立的哈夫曼树中,从叶结点开始,沿结点的双亲链域回退到根结点,每回退一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼码值。由于一个字符的哈夫曼编码是从根结点到相应叶结点所经过的路径上各分支所组成的 0、1 序列,因此先得到的分支代码为所求编码的低位,后得到的分支代码为所求编码的高位码。我们可以设置一个结构数组 huffcode 用来存放各字符的哈夫曼编码信息,数组元素的结构中有两个域:bit 和 start。其中,域 bit 为一维数组,用来保存字符的哈夫曼编码, start 表示该编码在数组 bit 中的开始位置。所以,对于第 i 个字符,它的哈夫曼编码存放在 huffcode[i].bit 中的从 huffcode[i].start 到 n 的 bit 位中。

#include<iostream>
#include<cstdio>

哈夫曼编码是一种用于数据压缩的算法。下面是C语言实现哈夫曼编码的示例代: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NODE_NUM 1000 typedef struct { int weight; int parent, lchild, rchild; } HuffmanNode; typedef struct { int bit[MAX_NODE_NUM]; int start; } HuffmanCode; void HuffmanCoding(HuffmanNode *huffmanTree, HuffmanCode *huffmanCode, int n) { int i, j, parent, left, right; for (i = 0; i < n; i++) { huffmanTree[i].parent = -1; huffmanTree[i].lchild = -1; huffmanTree[i].rchild = -1; } for (i = 0; i < n-1; i++) { int min1 = MAX_NODE_NUM, min2 = MAX_NODE_NUM; left = right = -1; for (j = 0; j < n+i; j++) { if (huffmanTree[j].parent == -1 && huffmanTree[j].weight < min1) { min2 = min1; right = left; min1 = huffmanTree[j].weight; left = j; } else if (huffmanTree[j].parent == -1 && huffmanTree[j].weight < min2) { min2 = huffmanTree[j].weight; right = j; } } huffmanTree[left].parent = n + i; huffmanTree[right].parent = n + i; huffmanTree[n + i].lchild = left; huffmanTree[n + i].rchild = right; huffmanTree[n + i].weight = min1 + min2; } for (i = 0; i < n; i++) { HuffmanCode *code = &huffmanCode[i]; code->start = n - 1; parent = huffmanTree[i].parent; while (parent != -1) { if (huffmanTree[parent].lchild == i) { code->bit[code->start] = 0; } else { code->bit[code->start] = 1; } code->start--; i = parent; parent = huffmanTree[parent].parent; } } } int main() { int i, n; HuffmanNode huffmanTree[MAX_NODE_NUM]; HuffmanCode huffmanCode[MAX_NODE_NUM]; printf("请输入叶子结点的个数:"); scanf("%d", &n); printf("请输入每个叶子结点的权重:"); for (i = 0; i < n; i++) { scanf("%d", &huffmanTree[i].weight); } HuffmanCoding(huffmanTree, huffmanCode, n); printf("哈夫曼编码表:\n"); for (i = 0; i < n; i++) { printf("结点%d的哈夫曼编码为:", i); int j; for (j = huffmanCode[i].start + 1; j < n; j++) { printf("%d", huffmanCode[i].bit[j]); } printf("\n"); } return 0; } ``` 该代中定义了两个结构体:`HuffmanNode`表示哈夫曼树中的结点,包括权值、父结点、左孩子和右孩子;`HuffmanCode`表示哈夫曼编码,包括二进制位以及起始位置。 在`HuffmanCoding`函数中,首先初始化哈夫曼树的每个结点,然后依次求出每个非叶子结点,直到只剩下一个根结点。接着遍历每个叶子结点,求出其哈夫曼编码。最后输出哈夫曼编码表。 在主函数中,首先输入叶子结点的个数和权重,然后调用`HuffmanCoding`函数求出哈夫曼编码,最后输出哈夫曼编码表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值