假设用于通信的电文仅由8个字母 {a, b, c, d, e, f, g, h} 构成,它们在电文中出现的概率分别为{ 0.07, 0.19, 0.02, 0.06, 0.32, 0.03, 0.21, 0.10 },试为这8个字母设计哈夫曼编码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXNODE 20
#define MAXINT 100
struct HtNode {
int ww;
int parent, lchild, rchild;
};
struct HtTree {
char root;
struct HtNode ht[MAXNODE];
};
typedef struct HtTree PHtTree;
PHtTree *huffman(int m, int *w) {
PHtTree *pht;
int i, j, x1, x2, m1, m2;
pht = (PHtTree *) malloc(sizeof(PHtTree));
if ( pht == NULL) {
printf("Out of space!!\n");
return pht;
}
for ( i = 0; i < 2 * m1 ; i++) {
pht->ht[i]. lchild = -1;
pht->ht[i]. rchild = -1;
pht->ht[i]. parent = -1;
if ( i < m)
pht->ht[i]. ww = w[i];
else
pht->ht[i]. ww = -1;
}
for ( i = 0; i < m - 1; i++) {
m1 = MAXINT;
m2 = MAXINT;
x1 = -1;
x2 = -1;
for ( j = 0; j < m + i; j++)
if ( pht->ht[j].ww < ml && pht->ht[j].parent == -1) {
m2 = ml;
x2 = x1;
m1 = pht->ht[j]. ww;
x1 = j;
} else if ( pht->ht[j]. ww < m2 && pht->ht[j]. parent == -1) {
m2 = pht->ht[j]. ww;
x2 = j;
}
pht->ht[x1]. parent = m + i;
pht->ht[x2]. parent = m + i;
pht->ht[m + i]. ww = m1 + m2;
pht->ht[m + i]. lchild = x1;
pht->ht[m + i]. rchild = x2;
}
pht->root = m + i - 1;
return pht;
}
void CrtHuffmanCode(PHtTree *pht, int i, int j) {
int a, b;
a = i;
b = j = pht->ht[i].parent;
if (pht->ht[j].parent != 0) {
i = j;
CrtHuffmanCode(pht, i, j);
}
if (pht->ht[b].lchild == a) {
printf("0");
} else {
printf("1");
}
}
int main() {
PHtTree *pht;
int w, i, j; //w表示权值
char k[8];//k表示获取的字符
for (i = 0; i < 8; i++) {
printf("请输入第%d个字符:", i + 1);
scanf("%c", &k[i]);
printf("请输入第%d个字符的权值:", i + 1);
scanf("%d", &w);
pht->ht[i].ww = w;
printf("\n");
}
huffman(8, k);
for (i = 1; i <= 8; i++) {
j = 0;
printf("\n%c\t", pht->root);
CrtHuffmanCode(pht, i, j);
printf("\n");
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义字母结构体
struct Node {
char letter;
float frequency;
struct Node* left;
struct Node* right;
};
// 创建新节点
struct Node* createNode(char letter, float frequency) {
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->letter = letter;
node->frequency = frequency;
node->left = NULL;
node->right = NULL;
return node;
}
// 比较函数,用于排序
int compareNodes(const void* a, const void* b) {
struct Node* node1 = *(struct Node**)a;
struct Node* node2 = *(struct Node**)b;
return (node1->frequency > node2->frequency) - (node1->frequency < node2->frequency);
}
// 构建哈夫曼树
struct Node* buildHuffmanTree(char letters[], float frequencies[], int n) {
struct Node** nodes = (struct Node**)malloc(n * sizeof(struct Node*));
for (int i = 0; i < n; i++) {
nodes[i] = createNode(letters[i], frequencies[i]);
}
while (n > 1) {
qsort(nodes, n, sizeof(struct Node*), compareNodes);
struct Node* left = nodes[0];
struct Node* right = nodes[1];
struct Node* parent = createNode('\0', left->frequency + right->frequency);
parent->left = left;
parent->right = right;
nodes[0] = parent;
nodes[1] = nodes[n - 1];
n--;
}
struct Node* root = nodes[0];
free(nodes);
return root;
}
// 为每个字母分配编码
void assignCodes(struct Node* node, char* code, int depth) {
if (node->left == NULL && node->right == NULL) {
code[depth] = '\0';
printf("%c: %s\n", node->letter, code);
return;
}
code[depth] = '0';
assignCodes(node->left, code, depth + 1);
code[depth] = '1';
assignCodes(node->right, code, depth + 1);
}
int main() {
char letters[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
float frequencies[] = {0.07, 0.19, 0.02, 0.06, 0.32, 0.03, 0.21, 0.10};
int n = sizeof(letters) / sizeof(letters[0]);
struct Node* root = buildHuffmanTree(letters, frequencies, n);
char code[100];
assignCodes(root, code, 0);
return 0;
}