假设用于通信的电文由字行集1,b.c.d.e:E2.h,m.口)中的字母构成,其中前8个字好(a,b,c.d.e,f.g,h)在电文中出现的概率分则为{0.07,0.11,0.001,0.02. 0. 005,0.01, 0. 14, 0.26},字母{m}在电文中出现的概率为考生学号最后三位数除以 1000 所得,比如某考生学号为:20101112,则以112/1000=0.112, 那么字母{m}出现的概率为 0. 112。已知十个字母出现的概率之和为 1。 1、根据《数据结构与算法》该门课程所学数据存储相关知识,通过用 VC 语言编程验证上述设计出的哈夫曼编码。
时间: 2024-03-19 21:43:18 浏览: 134
以下是用 VC 语言编写的验证哈夫曼编码的代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CHARACTERS 10
#define MAX_CODE_LENGTH 10
// 定义哈夫曼树的节点结构体
typedef struct node {
char character; // 字符
int weight; // 权重
struct node *left_child; // 左子节点
struct node *right_child; // 右子节点
} Node;
// 定义哈夫曼编码的结构体
typedef struct code {
char character; // 字符
char bits[MAX_CODE_LENGTH + 1]; // 编码
} Code;
// 构建哈夫曼树
Node *build_huffman_tree(char characters[], double weights[]) {
// 先将所有字符和权重都存入节点数组中
int n = MAX_CHARACTERS;
Node *nodes = (Node *) malloc(n * sizeof(Node));
for (int i = 0; i < n; i++) {
nodes[i].character = characters[i];
nodes[i].weight = (int) (weights[i] * 1000);
nodes[i].left_child = NULL;
nodes[i].right_child = NULL;
}
// 依次取出两个权重最小的节点,合并成一个新节点,并将新节点放回数组中
for (int i = 0; i < n - 1; i++) {
int min1 = -1, min2 = -1;
for (int j = 0; j < n; j++) {
if (nodes[j].weight > 0 && (min1 == -1 || nodes[j].weight < nodes[min1].weight)) {
min2 = min1;
min1 = j;
} else if (nodes[j].weight > 0 && (min2 == -1 || nodes[j].weight < nodes[min2].weight)) {
min2 = j;
}
}
nodes[min1].weight += nodes[min2].weight;
nodes[min2].weight = 0;
Node *new_node = (Node *) malloc(sizeof(Node));
new_node->character = '\0';
new_node->weight = nodes[min1].weight;
new_node->left_child = &nodes[min1];
new_node->right_child = &nodes[min2];
nodes[min1] = *new_node;
free(new_node);
}
// 返回根节点
for (int i = 0; i < n; i++) {
if (nodes[i].weight > 0) {
return &nodes[i];
}
}
return NULL;
}
// 递归地生成哈夫曼编码
void generate_huffman_codes(Node *node, char bits[], int length, Code codes[]) {
if (node->left_child == NULL && node->right_child == NULL) {
// 已经到达叶子节点,将编码存入数组中
Code new_code;
new_code.character = node->character;
strcpy(new_code.bits, bits);
codes[node->character - 'a'] = new_code;
} else {
// 继续递归生成编码
bits[length] = '0';
generate_huffman_codes(node->left_child, bits, length + 1, codes);
bits[length] = '1';
generate_huffman_codes(node->right_child, bits, length + 1, codes);
}
}
int main() {
// 定义字符集和权重
char characters[MAX_CHARACTERS + 1] = "abcdefghm";
double weights[MAX_CHARACTERS] = {0.07, 0.11, 0.001, 0.02, 0.005, 0.01, 0.14, 0.26};
// 计算字母 m 的出现概率
int student_id = 20101112;
double m_weight = (student_id % 1000) / 1000.0;
weights[MAX_CHARACTERS - 1] = m_weight;
// 构建哈夫曼树
Node *root = build_huffman_tree(characters, weights);
// 生成哈夫曼编码
Code codes[MAX_CHARACTERS];
char bits[MAX_CODE_LENGTH + 1] = "";
generate_huffman_codes(root, bits, 0, codes);
// 输出哈夫曼编码
for (int i = 0; i < MAX_CHARACTERS; i++) {
printf("%c: %s\n", codes[i].character, codes[i].bits);
}
return 0;
}
```
该程序首先定义了字符集和权重,然后根据题目所给的信息计算出字母 m 的出现概率,并将其作为权重数组的最后一个元素。接着,调用 `build_huffman_tree` 函数构建哈夫曼树,再调用 `generate_huffman_codes` 函数递归地生成哈夫曼编码。最后,输出每个字符的哈夫曼编码。
需要注意的是,由于题目要求输出的是 VC 语言程序,因此上述代码可能无法直接在其他编程语言中运行。但是,哈夫曼树和哈夫曼编码的实现思路是通用的,可以参考上述代码写出对应其他语言的程序。
阅读全文