鱼C论坛

 找回密码
 立即注册
查看: 1072|回复: 1

[已解决]关于c语言的哈夫曼树

[复制链接]
发表于 2023-5-7 21:39:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

#include<stdio.h>
#include<stdlib.h>

#define maxsize 50

typedef struct
{
        char data;
        int weight;
        int parent;
        int leftchild;
        int rightchild;
}HuffNode;

typedef struct
{
        char code[maxsize];
        int start;
}HuffCode;

int create_huffman(HuffNode *HN);

void PrintBTNode(HuffNode *HN, int index,int n,int level);

void encoding (HuffNode* HN,HuffCode *HC,int n);

int main()
{
        HuffNode HN[maxsize];
        int n=create_huffman(HN);  //n个叶子结点
        printf("哈夫曼树:\n");
        PrintBTNode (HN,2*n-1,n,0);
        HuffCode HC[maxsize];
        printf("哈夫曼编码:\n");
        encoding (HN,HC,n);
}

int create_huffman(HuffNode *HN)
{
        int n;
        int min1;
        int min2;
        int lnode;
        int rnode;
        printf("单词个数:");
        scanf("%d",&n);
        int i;
        for (i=1;i<=n;i++)
        {
                getchar();
                printf("请输入第%d个单词:",i);
                scanf("%c",&HN[i].data);
                printf("请输入第%d个单词的出现频度:",i);
                scanf("%d",&HN[i].weight);
        }
        for (i=1;i<=2*n-1;i++)
        {
                HN[i].parent=0;
                HN[i].leftchild=0;
                HN[i].rightchild=0;
        }
        int k;
        for (i=n+1;i<=2*n-1;i++)
        {
                min1=32767;
                min2=32767;
                lnode=1;
                rnode=1;
                for (k=1;k<=i-1;k++)    // 找1到i-1的两个最小权值结点
                {
                        if (HN[k].parent==0)
                        {
                                if (HN[k].weight<=min1)
                                {
                                        min2=min1;      //同下
                                        rnode=lnode;    //把原来的左孩子赋值给右孩子,右孩子更大
                                        min1=HN[k].weight;//同下
                                        lnode=k;          //新的左孩子
                                }
                                else if (HN[k].weight<=min2)
                                {
                                        min2=HN[k].weight;
                                        rnode=k;
                                }
                                HN[i].weight=min1+min2;
                                HN[i].leftchild=lnode;   //用下标表示孩子
                                HN[i].rightchild=rnode;
                                HN[lnode].parent=i;
                                HN[rnode].parent=i;
                        }
                }
        }
        return n;
}

void PrintBTNode(HuffNode *HN, int index,int n,int level)
{
        int i;
        if (index>2*n-1||index<1)
        {
                return;
        }
        PrintBTNode(HN,HN[index].rightchild,n,level+1);
        if (level!=0)
        {
                for (i=0;i<4*(level-1);i++)
                {
                        printf("%s"," ");
                }
                printf("%s","---");
        }
        if (index<=n)
        {
                printf("%c",HN[index].data);
        }
        else if (index>n)
        {
                printf("●");
        }
        printf("\n");
        PrintBTNode(HN,HN[index].leftchild,n,level+1);
}

void encoding (HuffNode* HN,HuffCode *HC,int n)
{
        HuffCode d;
        int i;
        int c;
        int f;
        for (i=1;i<=n;i++)  //叶子结点
        {
                d.start=n+1;   //叶子结点后的第一个父母结点
                c=i;
                f=HN[i].parent;   //叶子结点的父母
                while (f!=0)   //直到f=0->到树根
                {
                        if (HN[f].leftchild==c)
                        {
                                d.code[d.start-1]='0';  //
                                d.start=d.start-1;
                        }
                        else
                        {
                                d.code[d.start-1]='1';
                                d.start=d.start-1;
                        }
                        c=f;
                        f=HN[f].parent;
                }
                HC[i]=d;    //数组中的元素存字符串
                int k;
                for (i=1;i<=n;i++)
                {
                        printf("%c:",HN[i].data);
                        for (k=HC[i].start;k<=n;k++)
                        {
                                printf("%c",HC[i].code[k]);
                        }
                        printf("\n");
                }
        }
}
请问为啥输出的横向哈夫曼树和哈夫曼编码都是乱码呀
最佳答案
2023-5-7 21:39:34
这个问题可能是因为在Windows系统下,输出中文字符时默认使用的是GBK编码,而在代码中没有指定输出编码格式。可以在代码开头加上以下语句指定输出编码格式为UTF-8:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main() {
    setlocale(LC_ALL, "zh_CN.UTF-8");
    // ...
}

另外,在输出哈夫曼编码时,代码中存在一个错误, for 循环中的变量 i 被重复定义了,应该将其中一个改为 j 或其他未使用的变量名。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-7 21:39:34 | 显示全部楼层    本楼为最佳答案   
这个问题可能是因为在Windows系统下,输出中文字符时默认使用的是GBK编码,而在代码中没有指定输出编码格式。可以在代码开头加上以下语句指定输出编码格式为UTF-8:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main() {
    setlocale(LC_ALL, "zh_CN.UTF-8");
    // ...
}

另外,在输出哈夫曼编码时,代码中存在一个错误, for 循环中的变量 i 被重复定义了,应该将其中一个改为 j 或其他未使用的变量名。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 22:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表