用最简单的c语言代码写电文的编码和译码 任务:从键盘接收一串电文字符,输出对应的哈夫曼编码。同时,能翻译由哈夫曼编码生成的代码串,输出对应的电文字符串。 ①构造一棵哈夫曼树;②实现哈夫曼编码,并用哈夫曼编码生成的代码串进行译码;③程序中字符和权值是可变的,实现程序的灵活性。
时间: 2023-05-27 15:03:41 浏览: 150
参考代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CHAR_NUM 256
typedef struct HuffmanNode{
char ch; // 节点代表的字符,如果是内部节点则为'\0'
int weight; // 权值
struct HuffmanNode *left, *right; // 左右子节点指针
}HuffmanNode, *HuffmanTree;
void CountCharFrequency(char *str, int *freq){ // 统计字符出现的频率
int len = strlen(str);
for(int i = 0; i < len; ++i){
++freq[(int)str[i]];
}
}
HuffmanTree CreateHuffmanTree(int *freq){ // 创建哈夫曼树
HuffmanTree nodes[MAX_CHAR_NUM] = {NULL};
int nodeNum = 0;
for(int i = 0; i < MAX_CHAR_NUM; ++i){
if(freq[i] > 0){
HuffmanNode *node = (HuffmanNode*)malloc(sizeof(HuffmanNode));
node->ch = (char)i;
node->weight = freq[i];
node->left = node->right = NULL;
nodes[nodeNum++] = node;
}
}
while(nodeNum > 1){
int minIdx1 = 0, minIdx2 = 1;
if(nodes[minIdx1]->weight > nodes[minIdx2]->weight)
minIdx1 = 1, minIdx2 = 0;
for(int i = 2; i < nodeNum; ++i){
if(nodes[i]->weight < nodes[minIdx1]->weight){
minIdx2 = minIdx1;
minIdx1 = i;
}
else if(nodes[i]->weight < nodes[minIdx2]->weight){
minIdx2 = i;
}
}
HuffmanNode *newNode = (HuffmanNode*)malloc(sizeof(HuffmanNode));
newNode->ch = '\0';
newNode->weight = nodes[minIdx1]->weight + nodes[minIdx2]->weight;
newNode->left = nodes[minIdx1];
newNode->right = nodes[minIdx2];
nodes[minIdx1] = newNode;
nodes[minIdx2] = nodes[--nodeNum];
}
return nodes[0];
}
void DestroyHuffmanTree(HuffmanTree tree){ // 销毁哈夫曼树
if(tree){
DestroyHuffmanTree(tree->left);
DestroyHuffmanTree(tree->right);
free(tree);
}
}
void PrintHuffmanTree(HuffmanTree tree, char *buffer, int k){ // 输出哈夫曼树
if(tree){
if(tree->ch != '\0')
printf("%c: %s\n", tree->ch, buffer);
buffer[k] = '0';
PrintHuffmanTree(tree->left, buffer, k+1);
buffer[k] = '1';
PrintHuffmanTree(tree->right, buffer, k+1);
}
}
void HuffmanEncoding(HuffmanTree tree, char *buffer, char *str){ // 哈夫曼编码
int len = strlen(str);
for(int i = 0; i < len; ++i){
HuffmanNode *p = tree;
while(p->left != NULL && p->right != NULL){ // 循环遍历直到叶节点
if(str[i] == '0')
p = p->left;
else
p = p->right;
}
printf("%s", buffer); // 输出哈夫曼编码
buffer[0] = '\0';
strcat(buffer, "");
strcat(buffer, tree->ch == '\0' ? " " : &tree->ch); // 重新置为根节点
}
}
void HuffmanDecoding(HuffmanTree tree, char *str){ // 哈夫曼译码
int len = strlen(str);
HuffmanNode *p = tree;
for(int i = 0; i < len; ++i){
if(str[i] == '0') // 走左边
p = p->left;
else if(str[i] == '1') // 走右边
p = p->right;
if(p->left == NULL && p->right == NULL){ // 到达叶节点,输出字符
printf("%c", p->ch);
p = tree; // 重新置为根节点
}
}
}
int main(){
char str[MAX_CHAR_NUM] = {0};
int freq[MAX_CHAR_NUM] = {0};
printf("Please input the message: ");
scanf("%s", str);
CountCharFrequency(str, freq); // 统计字符出现频率
HuffmanTree tree = CreateHuffmanTree(freq); // 创建哈夫曼树
char buffer[MAX_CHAR_NUM] = {0};
printf("The encoding of each character is:\n");
PrintHuffmanTree(tree, buffer, 0); // 输出哈夫曼树
printf("The huffman encoding of the message is: ");
HuffmanEncoding(tree, buffer, str); // 哈夫曼编码
printf("\nPlease input the huffman code: ");
scanf("%s", buffer);
printf("The message generated from the huffman code is: ");
HuffmanDecoding(tree, buffer); // 哈夫曼译码
printf("\n");
DestroyHuffmanTree(tree); // 销毁哈夫曼树
return 0;
}
阅读全文