Yester07 2022-06-28 11:05 采纳率: 48.5%

C语言哈夫曼树编码及其解码

1.解决上述问题，将字符数据翻译为哈夫曼树编码
2.完成对解码部分的代码

``````#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
typedef struct TreeNode  //定义树结点
{
int weight;  //权值
int parent;
int lchild;
int rchild;
char ch;
}treenode;

typedef struct HuffmanTree  //定义huffmantree，用数组表示树
{
treenode* data;
int length;
}huffmantree;

huffmantree* huffmantree_create(int weight[], int length, char character[])//huffmantree初始化
{
huffmantree* tree = (huffmantree*)malloc(sizeof(huffmantree));
tree->data = (treenode*)malloc(sizeof(treenode) * (2 * length - 1));  //n个元素，树中有2n-1个结点
tree->length = length;
for (int i = 0; i < length; i++)
{
tree->data[i].weight = weight[i];
tree->data[i].parent = 0;
tree->data[i].lchild = -1;
tree->data[i].rchild = -1;
tree->data[i].ch = character[i];
}
return tree;
}

int* selectMin(huffmantree* tree)//选择最小的两个结点
{
int min=10000, secmin=10000;
int minIndex, secminIndex;
for (int i = 0; i < tree->length; i++)  //找到最小的结点的索引下标
{
if (tree->data[i].parent == 0)
{
if (tree->data[i].weight < min)
{
min = tree->data[i].weight;
minIndex = i;
}
}
}
for (int i = 0; i < tree->length; i++)  //找到第二小的结点的索引下标
{
if (tree->data[i].parent == 0 && i != minIndex)
{
if (tree->data[i].weight < secmin)
{
secmin = tree->data[i].weight;
secminIndex = i;
}
}
}
int* res = (int*)malloc(sizeof(int) * 2);  //返回两个数据，用int数组返回
res[0] = minIndex;
res[1] = secminIndex;
return res;
}

void createTree(huffmantree* tree)  //建树
{
int min;
int secmin;
int* res;
for (int i = tree->length; i < tree->length * 2 - 1; i++)
{
res = selectMin(tree);
printf("%d %d\t", res[0], res[1]);
min = res[0];
secmin = res[1];
tree->data[i].weight = tree->data[min].weight + tree->data[secmin].weight;
tree->data[min].parent = i;  //设置双亲结点
tree->data[secmin].parent = i;
tree->data[i].parent = 0;
tree->data[i].lchild = min;  //设置孩子结点
tree->data[i].rchild = secmin;
tree->length++;
}
}

void preorder(huffmantree* tree,int index)
{
while (index != -1)
{
printf("%c %d\n", tree->data[index].ch, tree->data[index].weight);
preorder(tree, tree->data[index].lchild);
preorder(tree, tree->data[index].rchild);
}
}

int main()
{
FILE* fp;
char ch, str[100],character[100];
int length = 0, option, lengthchar = 0, weight[100];
fp = fopen("test3.txt", "r+");
if (fp == NULL)
{
printf("打开文件失败\n");
exit(0);
}
printf("打开文件成功\n");
ch = fgetc(fp);
while (ch != EOF)
{
str[length] = ch;
length++;
ch = fgetc(fp);
}
str[length] = '\0';
printf("该文件的数据为:");
puts(str);
printf("请问你是要对文件进行加密还是进行解密？(输入1为加密，输入2为解密)");
printf("我选择：");
scanf("%d", &option);
while (option != 1 && option != 2)
{
printf("你的输入有误，请重新输入！\n我选择：");
scanf("%d", &option);
}
if (option == 1)  //对数据进行huffmantree编码
{
int status;
huffmantree* hftree;
for (int i = 0; i < length; i++)  //先把str中的每一个字符都单列出来放进数组character
{
status = 0;
for (int t = 0; t < lengthchar; t++)
{
if (str[i] == character[t])
{
status = 1;
break;
}
}
if (status == 1)
continue;
character[lengthchar] = str[i];
lengthchar++;
}
character[lengthchar] = '\0';
printf("字符数组为:");
puts(character);
for (int i = 0; i < lengthchar; i++)  //将权值数组归0
{
weight[i] = 0;
}
for (int i = 0; i < lengthchar; i++)  //设置权值数组
{
for (int t = 0; t < length; t++)
{
if (str[t] == character[i])  //统计每个字符的出现次数
weight[i]++;
}
}
printf("权值数组为:");
for (int i = 0; i < lengthchar; i++)
printf("%d ", weight[i]);
printf("\n");
hftree = huffmantree_create(weight, lengthchar, character);
createTree(hftree);
preorder(hftree,hftree->length-1);
}
if (option == 2)//对huffmantree编码进行解码
{

}
fclose(fp);
return 0;
}

``````
• 写回答

4条回答默认 最新

• emXiaoMing 2022-06-28 11:19
关注

因为有某次调用selectMin()函数时没有进54行那个分支，导致secminIndex没有初始化就赋值给了res[1]

本回答被题主选为最佳回答 , 对您是否有帮助呢?
评论 编辑记录

• 系统已结题 7月7日
• 已采纳回答 6月29日
• 创建了问题 6月28日

悬赏问题

• ¥40 如果update 一个列名为参数的value
• ¥15 基于51单片机的水位检测系统设计中LCD1602一直不显示
• ¥15 OCS2安装出现问题，请大家给点意见
• ¥15 ros小车启动launch文件报错
• ¥15 vs2015到期想登陆但是登陆不上
• ¥15 IPQ5018制作烧录固件，boot运行失败(操作系统-linux)（相关搜索：操作系统）（相关搜索：操作系统）
• ¥20 icefall在librispeech基础上加入个人数据集
• ¥30 keepalive高可用故障运维配置询问
• ¥15 求帮助！国家电网内网u盘突然识别不出来了。
• ¥15 matlab语音变速变调同时实现