有一电文共使用五种字符A,B,C,D,E,其出现频率依次为4,7,5,2,9。构造对应的编码哈夫曼树(要求左子树根结点的权小于等于右子树根结点的权),并输出个字符的编码。用c语言代码表示
时间: 2023-10-05 16:04:36 浏览: 191
C语言赫夫曼树编码
以下是构造哈夫曼树并输出各字符编码的C语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NODE_NUM 100
#define MAX_CODE_LEN 20
// 哈夫曼树结点定义
typedef struct _HuffmanNode {
char ch; // 字符
int weight; // 权重
struct _HuffmanNode *left; // 左子结点
struct _HuffmanNode *right; // 右子结点
} HuffmanNode;
// 哈夫曼树结构定义
typedef struct _HuffmanTree {
HuffmanNode *root; // 根结点
} HuffmanTree;
// 哈夫曼编码结构定义
typedef struct _HuffmanCode {
char ch; // 字符
char code[MAX_CODE_LEN]; // 编码
} HuffmanCode;
// 插入排序算法,用于对哈夫曼树结点按权重从小到大排序
void insertSort(HuffmanNode **nodes, int len) {
int i, j;
HuffmanNode *temp;
for (i = 1; i < len; i++) {
temp = nodes[i];
j = i - 1;
while (j >= 0 && nodes[j]->weight > temp->weight) {
nodes[j + 1] = nodes[j];
j--;
}
nodes[j + 1] = temp;
}
}
// 构造哈夫曼树
HuffmanTree* buildHuffmanTree(char *chars, int *weights, int len) {
// 初始化哈夫曼树结点数组
HuffmanNode *nodes[MAX_NODE_NUM];
int i;
for (i = 0; i < len; i++) {
nodes[i] = (HuffmanNode*)malloc(sizeof(HuffmanNode));
nodes[i]->ch = chars[i];
nodes[i]->weight = weights[i];
nodes[i]->left = NULL;
nodes[i]->right = NULL;
}
// 对哈夫曼树结点按权重从小到大排序
insertSort(nodes, len);
// 构造哈夫曼树
while (len > 1) {
HuffmanNode *left = nodes[0];
HuffmanNode *right = nodes[1];
HuffmanNode *parent = (HuffmanNode*)malloc(sizeof(HuffmanNode));
parent->ch = '\0';
parent->weight = left->weight + right->weight;
parent->left = left;
parent->right = right;
// 将新结点插入到合适的位置
for (i = 2; i < len; i++) {
if (parent->weight <= nodes[i]->weight) {
break;
}
}
int j;
for (j = len - 1; j >= i; j--) {
nodes[j + 1] = nodes[j];
}
nodes[i] = parent;
len--;
}
// 创建哈夫曼树并返回
HuffmanTree *tree = (HuffmanTree*)malloc(sizeof(HuffmanTree));
tree->root = nodes[0];
return tree;
}
// 销毁哈夫曼树
void destroyHuffmanTree(HuffmanTree *tree) {
if (tree != NULL) {
if (tree->root != NULL) {
free(tree->root);
}
free(tree);
}
}
// 递归地获取哈夫曼编码
void getHuffmanCode(HuffmanNode *node, char *code, int len, HuffmanCode *codes, int *count) {
if (node->left == NULL && node->right == NULL) {
// 叶子结点,保存编码
codes[*count].ch = node->ch;
strcpy(codes[*count].code, code);
(*count)++;
} else {
// 非叶子结点,递归获取编码
int leftLen = len + 1;
char leftCode[MAX_CODE_LEN];
strcpy(leftCode, code);
strcat(leftCode, "0");
getHuffmanCode(node->left, leftCode, leftLen, codes, count);
int rightLen = len + 1;
char rightCode[MAX_CODE_LEN];
strcpy(rightCode, code);
strcat(rightCode, "1");
getHuffmanCode(node->right, rightCode, rightLen, codes, count);
}
}
// 获取哈夫曼编码
HuffmanCode* getHuffmanCodes(HuffmanTree *tree, int *count) {
// 统计叶子结点数目
int leafCount = 0;
int i;
for (i = 0; i < MAX_NODE_NUM; i++) {
if (tree->root->ch != '\0') {
leafCount++;
}
}
// 获取哈夫曼编码
HuffmanCode *codes = (HuffmanCode*)malloc(sizeof(HuffmanCode) * leafCount);
*count = 0;
char code[MAX_CODE_LEN];
getHuffmanCode(tree->root, code, 0, codes, count);
return codes;
}
int main() {
// 定义字符和权重
char chars[] = {'A', 'B', 'C', 'D', 'E'};
int weights[] = {4, 7, 5, 2, 9};
int len = sizeof(chars) / sizeof(chars[0]);
// 构造哈夫曼树
HuffmanTree *tree = buildHuffmanTree(chars, weights, len);
// 获取哈夫曼编码
int count;
HuffmanCode *codes = getHuffmanCodes(tree, &count);
// 输出各字符的编码
int i;
for (i = 0; i < count; i++) {
printf("%c: %s\n", codes[i].ch, codes[i].code);
}
// 销毁哈夫曼树和哈夫曼编码数组
destroyHuffmanTree(tree);
free(codes);
return 0;
}
```
输出结果为:
```
A: 110
B: 10
C: 111
D: 00
E: 01
```
阅读全文