请用C语言写程序实现输入n个叶子结点的权值构造哈夫曼树;根据哈夫曼树构造哈夫曼编码,并对密文完成解码工作。
时间: 2023-06-29 16:15:14 浏览: 105
根据给定的n个权值构造哈夫曼树。通过遍历此二叉树完成哈夫曼编码。
4星 · 用户满意度95%
好的,下面是用C语言实现输入n个叶子结点的权值构造哈夫曼树;根据哈夫曼树构造哈夫曼编码,并对密文完成解码工作的程序:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NODE_NUM 100
#define MAX_BIT_NUM 100
typedef struct HuffmanNode {
int weight;
int parent;
int leftChild;
int rightChild;
} HuffmanNode, *PHuffmanNode;
void buildHuffmanTree(PHuffmanNode nodes, int n);
void buildHuffmanCode(PHuffmanNode nodes, int n, char **code, int *codeLen);
void encode(char *text, char **code, int *codeLen, char *ciphertext);
void decode(PHuffmanNode nodes, int n, char *ciphertext, int len, char *text);
int main() {
int n, i;
int weight[MAX_NODE_NUM];
char *code[MAX_NODE_NUM];
int codeLen[MAX_NODE_NUM];
char text[MAX_NODE_NUM];
char ciphertext[MAX_BIT_NUM];
printf("请输入叶子结点的个数:");
scanf("%d", &n);
printf("请输入%d个叶子结点的权值:\n", n);
for(i = 0; i < n; i++) {
scanf("%d", &weight[i]);
}
PHuffmanNode nodes = (PHuffmanNode)malloc(sizeof(HuffmanNode) * (2 * n - 1));
for(i = 0; i < 2 * n - 1; i++) {
nodes[i].weight = 0;
nodes[i].parent = -1;
nodes[i].leftChild = -1;
nodes[i].rightChild = -1;
}
for(i = 0; i < n; i++) {
nodes[i].weight = weight[i];
}
buildHuffmanTree(nodes, n);
buildHuffmanCode(nodes, n, code, codeLen);
printf("请输入要加密的文本:");
scanf("%s", text);
encode(text, code, codeLen, ciphertext);
printf("加密后的文本:%s\n", ciphertext);
char decodeText[MAX_NODE_NUM];
decode(nodes, n, ciphertext, strlen(ciphertext), decodeText);
printf("解密后的文本:%s\n", decodeText);
return 0;
}
void buildHuffmanTree(PHuffmanNode nodes, int n) {
int i, j, min1, min2;
for(i = n; i < 2 * n - 1; i++) {
min1 = min2 = 1000000;
nodes[i].leftChild = -1;
nodes[i].rightChild = -1;
for(j = 0; j < i; j++) {
if(nodes[j].parent == -1) {
if(nodes[j].weight < min1) {
min2 = min1;
min1 = nodes[j].weight;
nodes[i].leftChild = j;
} else if(nodes[j].weight < min2) {
min2 = nodes[j].weight;
nodes[i].rightChild = j;
}
}
}
nodes[i].weight = min1 + min2;
nodes[nodes[i].leftChild].parent = i;
nodes[nodes[i].rightChild].parent = i;
}
}
void buildHuffmanCode(PHuffmanNode nodes, int n, char **code, int *codeLen) {
int i, j, p;
char *cd = (char*)malloc(sizeof(char) * n);
cd[n - 1] = '\0';
for(i = 0; i < n; i++) {
int start = n - 1;
for(p = i, j = nodes[i].parent; j != -1; p = j, j = nodes[j].parent) {
if(nodes[j].leftChild == p) {
cd[--start] = '0';
} else {
cd[--start] = '1';
}
}
codeLen[i] = n - start;
code[i] = (char*)malloc(sizeof(char) * codeLen[i]);
strcpy(code[i], &cd[start]);
}
free(cd);
}
void encode(char *text, char **code, int *codeLen, char *ciphertext) {
int i, j, k;
for(i = 0; text[i] != '\0'; i++) {
for(j = 0; j < MAX_NODE_NUM; j++) {
if(text[i] == j + 'a') {
break;
}
}
for(k = 0; k < codeLen[j]; k++) {
ciphertext[i * codeLen[0] + k] = code[j][k];
}
}
ciphertext[i * codeLen[0]] = '\0';
}
void decode(PHuffmanNode nodes, int n, char *ciphertext, int len, char *text) {
int i, j, p = 2 * n - 2;
for(i = 0; i < len; i++) {
if(ciphertext[i] == '0') {
p = nodes[p].leftChild;
} else {
p = nodes[p].rightChild;
}
if(nodes[p].leftChild == -1 && nodes[p].rightChild == -1) {
for(j = 0; j < n; j++) {
if(nodes[p].weight == nodes[j].weight) {
break;
}
}
text[i / n] = j + 'a';
p = 2 * n - 2;
}
}
text[i / n] = '\0';
}
```
程序中,我们先输入叶子结点的个数和它们的权值,然后调用 `buildHuffmanTree` 函数构造哈夫曼树,调用 `buildHuffmanCode` 函数构造哈夫曼编码,调用 `encode` 函数对文本进行加密,调用 `decode` 函数对密文进行解密。其中,用 `HuffmanNode` 结构体来表示哈夫曼树的节点,用 `code` 数组来存储哈夫曼编码,用 `text` 和 `ciphertext` 分别存储原文和密文。
希望这个程序能够帮助您实现输入n个叶子结点的权值构造哈夫曼树;根据哈夫曼树构造哈夫曼编码,并对密文完成解码工作。如果您还有其他问题,请随时提出。
阅读全文