哈夫曼树的c语言实现
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
### 哈夫曼树的C语言实现 #### 一、引言 本文将详细介绍如何在C语言中实现哈夫曼树(又称最优二叉树),包括构建过程、哈夫曼编码的生成以及如何对输入的字符串进行编码。哈夫曼树是一种带权路径长度最短的二叉树,它在数据压缩领域有着广泛的应用。 #### 二、哈夫曼树的基本概念 哈夫曼树是一种特殊的二叉树,它的每个叶子节点都代表一个字符,并且该字符的出现频率作为其权重。通过构建哈夫曼树可以得到每个字符对应的哈夫曼编码,这是一种前缀编码,即任一字符的编码都不是其他字符编码的前缀。 #### 三、程序框架及核心函数介绍 ##### 1. 数据结构定义 ```c typedef struct Node { char ch; int weight; // 权重 int parent; int lchild, rchild; } HFNode; typedef struct { char ch; char code[NUM]; } HFCharCode; ``` - **HFNode**:表示哈夫曼树中的节点,包含字符、权重、父节点和左右孩子节点的索引。 - **HFCharCode**:存储字符及其对应的哈夫曼编码。 ##### 2. 核心函数说明 - **Statistics()**:统计每个字符的出现次数,并存储到`AllWeight`数组中。 - **CreateHFTree()**:根据`AllWeight`数组构建哈夫曼树。 - **CreateHFCode()**:为每个字符生成哈夫曼编码。 - **EncodeStr()**:对输入的字符串进行哈夫曼编码。 #### 四、代码分析 ##### 1. 统计字符频次 - Statistics() 此函数首先读取文件中的内容,并统计每个字符出现的次数,然后存储到`AllWeight`数组中。 ```c void Statistics() { int len = strlen(EnterStr); for (int i = 0; i <= 27; i++) AllWeight[i] = 0; for (int j = 0; j <= len - 1; j++) { if (isalpha(EnterStr[j])) { EnterStr[j] = tolower(EnterStr[j]); AllWeight[EnterStr[j] - 'a']++; } else if ((int)EnterStr[j] == 44) { AllWeight[26]++; } else if ((int)EnterStr[j] == 46) { AllWeight[27]++; } else { printf("\n输入不符合要求!\n\n"); exit(-1); } } // 继续处理 AllWeight 数组 } ``` 这里需要注意的是,对于输入的字符进行了规范化处理,确保了所有的字母都是小写,并且只考虑了字母、逗号和句号三种符号。 ##### 2. 构建哈夫曼树 - CreateHFTree() 构建哈夫曼树的过程中,首先需要初始化所有节点的父节点和子节点索引为-1,然后根据`AllWeight`数组创建叶子节点,并按权重从小到大排序,接着不断选择两个最小权重的节点合并,直到生成整棵树。 ```c void CreateHFTree() { int i; for (i = 0; i <= LeafNum - 1; i++) { HT[i].parent = -1; HT[i].lchild = -1; HT[i].rchild = -1; HT[i].weight = HT[i].weight; } // 后续构建过程省略 } ``` 在这个过程中,每个节点的`weight`属性已经由`Statistics()`函数设置好了。 ##### 3. 生成哈夫曼编码 - CreateHFCode() 生成哈夫曼编码的过程是遍历哈夫曼树,为每个叶子节点分配编码。通常从根节点出发,向左走记为0,向右走记为1,到达叶子节点时得到的就是该字符的哈夫曼编码。 ```c void CreateHFCode() { // 生成哈夫曼编码的逻辑 } ``` #### 五、总结 本程序通过几个关键步骤实现了哈夫曼树的构建及哈夫曼编码的生成,能够有效地对输入的字符串进行压缩。哈夫曼树作为一种非常实用的数据结构,在实际应用中有着广泛的应用场景,如文件压缩、数据传输等领域。
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <ctype.h>
#define MAX 999999 //一个极大值
#define NUM 10
//存储哈夫曼树每个结点
typedef struct Node {
char ch;
int weight; //权值
int parent;
int lchild, rchild;
}HFNode;
//存储每个字符及其哈夫曼编码
typedef struct {
char ch;
char code[NUM];
}HFCharCode;
HFNode HT[28 * 2 - 1]; //哈夫曼树结构体
HFCharCode HCD[28]; //哈夫曼编码结构体
int LeafNum; //叶子结点数
int NodeNum; //所有结点数
char EnterStr[MAX]; //输入的待编码电文
int AllWeight[28]; //存储所有28个字符的权值
void Statistics();
void CreateHFTree();
void CreateHFCode();
void ReverseStr(char *str);
void EncodeStr();
void InputStr();
int main() {
printf("****** 哈夫曼编码 ******\n\n");
printf("***********文件读取字符串******\n");
InputStr();
Statistics();
CreateHFTree();
CreateHFCode();
EncodeStr();
printf("\n编码结束请查看文件!");
return 0;
}
void InputStr() {
FILE * fp = fopen("source.txt", "r");
char ch;
int i = 0;
while (!feof(fp))
{
ch = fgetc(fp);
if (ch == -1)break;
EnterStr[i++] = ch;
}
fclose(fp);
}
//统计每个字符权值
剩余7页未读,继续阅读
- 粉丝: 1220
- 资源: 78
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
- 1
- 2
前往页