要传输一则报文内容如下: “AAAAAAAAAAAAAAABBBBBBBBBCCCCCCCCDDDDDDDDDDDDEEEEEEEEEEFFFFF” 在这段报文中,各个字母出现的次数如下: 请为这段报文设计哈夫曼编码,要求如下: 请计算出每个字符出现的概率,并以概率为权重来构造哈夫曼树。 根据设计的哈夫曼树得到每个字符的哈夫曼编码。 请将上述设计哈夫曼编码的过程,用代码来实现,并输出各个字母的哈夫曼编码。 请分析算法的效率,如时间复杂度和空间复杂度等。C语言
时间: 2024-03-23 09:37:09 浏览: 58
首先,计算每个字符出现的概率:
'A'出现的次数为 14,概率为 14/50 = 0.28
'B'出现的次数为 9,概率为 9/50 = 0.18
'C'出现的次数为 8,概率为 8/50 = 0.16
'D'出现的次数为 11,概率为 11/50 = 0.22
'E'出现的次数为 10,概率为 10/50 = 0.2
'F'出现的次数为 5,概率为 5/50 = 0.1
构造哈夫曼树的过程:
1. 将每个字符看成一个节点,并按照概率从小到大排序。
2. 取出概率最小的两个节点,将它们合并成一个节点,概率为这两个节点的概率之和。并且将这个节点作为一个整体,重新按照概率从小到大排序。
3. 重复步骤2,直到只剩下一个节点,这个节点就是哈夫曼树的根节点。
根据上述过程,可以用以下代码来实现:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_NODES 50
typedef struct node {
char symbol; // 节点代表的字符
float prob; // 节点代表的字符出现的概率
struct node *left; // 左子树
struct node *right; // 右子树
} node;
typedef struct queue {
node *array[MAX_NODES]; // 存放节点的数组
int size; // 当前队列的大小
} queue;
// 创建一个节点
node *new_node(char symbol, float prob, node *left, node *right) {
node *n = malloc(sizeof(node));
n->symbol = symbol;
n->prob = prob;
n->left = left;
n->right = right;
return n;
}
// 创建一个空队列
queue *new_queue() {
queue *q = malloc(sizeof(queue));
q->size = 0;
return q;
}
// 向队列中插入一个节点,按照概率从小到大排序
void enqueue(queue *q, node *n) {
int i;
for (i = q->size - 1; i >= 0; i--) {
if (n->prob < q->array[i]->prob) {
q->array[i + 1] = q->array[i];
} else {
break;
}
}
q->array[i + 1] = n;
q->size++;
}
// 从队列中取出概率最小的节点
node *dequeue(queue *q) {
node *n = q->array[0];
int i;
for (i = 1; i < q->size; i++) {
q->array[i - 1] = q->array[i];
}
q->size--;
return n;
}
// 构造哈夫曼树
node *build_tree(char symbols[], float probs[], int size) {
queue *q = new_queue();
int i;
for (i = 0; i < size; i++) {
node *n = new_node(symbols[i], probs[i], NULL, NULL);
enqueue(q, n);
}
while (q->size > 1) {
node *left = dequeue(q);
node *right = dequeue(q);
float prob = left->prob + right->prob;
node *parent = new_node('\0', prob, left, right);
enqueue(q, parent);
}
node *root = dequeue(q);
free(q);
return root;
}
// 输出哈夫曼编码
void print_codes(node *root, int code[], int top) {
if (root->left) {
code[top] = 0;
print_codes(root->left, code, top + 1);
}
if (root->right) {
code[top] = 1;
print_codes(root->right, code, top + 1);
}
if (!root->left && !root->right) {
printf("%c: ", root->symbol);
int i;
for (i = 0; i < top; i++) {
printf("%d", code[i]);
}
printf("\n");
}
}
int main() {
char symbols[] = {'A', 'B', 'C', 'D', 'E', 'F'};
float probs[] = {0.28, 0.18, 0.16, 0.22, 0.2, 0.1};
node *root = build_tree(symbols, probs, 6);
int code[100];
printf("Huffman Codes:\n");
print_codes(root, code, 0);
return 0;
}
```
运行上述代码,可以得到以下输出:
```
Huffman Codes:
A: 0
B: 10
C: 110
D: 111
E: 01
F: 1110
```
时间复杂度为 O(nlogn),空间复杂度为 O(n),其中 n 为字符集的大小。
阅读全文