精华内容
下载资源
问答
  • 哈夫曼编码译码c语言
    2021-05-21 11:01:44

    PAGE

    PAGE #

    PAGE

    PAGE #

    一、需求分析

    目前,进行快速远距离通信的主要手段是电报, 即将需传送的文字转化成由二级制的字符组成的字 符串。例如,假设需传送的电文为“ ABACCDA ”, 它只有4种字符,只需两个字符的串,便可以分辨。 假设A、B、C、D、的编码分别为00,01,10和11, 则上述7个字符的电文便为“ 0001001010110(”,总 长14位,对方接受时,可按二位一分进行译码。

    当然,在传送电文时,希望总长尽可能地短。如 果对每个字符设计长度不等的编码,且让电文中出现 次数较多的字符采用尽可能短的编码,则传送电文的 总长便可减少。如果设计 A、B、C、D的编码分别 为0,00,1,01,则上述7个字符的电文可转换成总长为 9的字符串“ 000011010'。但是,这样的电文无法翻 译,例如传送过去的字符串中前4个字符的字串

    “ 0000”就可以有很多种译法,或是“ AAAA ”或者 “ BB ”,或者“ ABA ”等。因此,若要设计长短不等 的编码,则必须是任一字符的编码都不是另一个字符 的编码的前缀,这种编码称作前缀编码。

    然而,如何进行前缀编码就是利用哈夫曼树来

    做,也就有了现在的哈夫曼编码和译码。

    二、概要设计

    利用哈夫曼树编/译码

    (一人建立哈夫曼树

    (一人

    建立哈夫曼树

    (二人 对哈夫曼树进行编码

    (三)、输出对应字符的编码

    译码过程

    主要代码实现:

    struct code〃结构体的定义

    char a; int w;

    int parent; int (child; int rchild;

    void creation(code *p,int njnt m); //建立哈夫曼树

    〃编码void coding(code *p,int n);

    〃编码

    void displays code 木pjnt njnt m); 〃输出函数

    void translate* char *^hc,code wp,int n);

    三、详细设计

    x~)>

    x~)>建立哈夫曩树

    宀 o ooo

    64623 4 3 6 13图图

    646

    23 4 3 6 1

    3

    (一)、对哈夫曼树进行编码主要代码实现:

    (一)、对哈夫曼树进行编码

    从叶子到根逆for(c=i,f=p[i].pare nt;f!=O;c=f,f=p[f].pare nt) {

    从叶子到根逆

    if(p[f]」child==c)

    {

    } else//右孩子编码为'1' 01

    } else

    //右孩子编码为'1' 01

    {

    cd[--start]='1:

    }

    }

    (二)、输出对应字符的码

    字符

    编码

    a

    110

    b

    111

    c

    10

    d

    0

    三)、译码过程 要代码实现:

    if(strcmp(a,hc[i])==O) //比较两个字符串是否相等,

    则输出0

    for(c=2* n-1,j=0;a[j]!='\0';j++)

    'O'或'1'确定找左孩子或右孩子

    {

    if(a[j]=='0')〃左孩子

    {

    c=p[c].lchild;

    }

    else

    //从根出发,按字从跟到叶子顺0 1{

    //从根出发,按字

    从跟到叶子顺

    0 1

    c=p[c].rchild;II 右孩子

    ”的藪字血入雾冲號字臓第if ?数罕运和字母的输图

    ”的藪字血入雾冲號字臓第if ?数罕运和

    字母的输

    S'

    s and S

    制⑴?用扎臺个数号:按峯一个鮒字返帶》

    H 修新轲人1

    也字桃1职臺靜入一个数和=

    三、调试分析

    数字的输入判断

    巒心咲?<二二二二二二

    g新输人

    )丄丄i11111

    gWfftA.

    涣定?Cluu*u*?KLt s

    涣定?Cluu*u*?KLt s anil Sr lt,jLTk£ff \ AiLa.JLiuLsli.ajLiixA it Hi '.buf 1 sulX Vebu.E ^ iLuLlM^ ..

    程序是否继续进行的萨卸

    判断

    lifl

    毛否誉滞 '汽術几用者V)否曲辿”

    |lBTe^E; -Bjay hey 七? k. ohi t. iiiiAE!

    四、用户手册

    (一)、首先根据提示输入初始化数据,提示输入一 个数字,请输入一个数a,0

    (二)在某一界面结束后,会有“请按回车继续下面 操作"提示,请按提示进行操作,如输入其他数字则 无效,知道输入回车符界面才会跳转。

    (三)对界面的操作可以自行选择,在询问是否译码 的时候,请按

    更多相关内容
  • 哈夫曼编码译码C语言编写[参考].pdf
  • 哈夫曼编码译码C语言编写 10 [?标签 哈夫曼, 编码, 译码?] 如上题 C语言编个程序 懂的帮搞个能运行的程序来#11别到网上找那些 我找过了没用的 蝶风待夕魂 回答:2 人气:19 解决时间:2009-05-14 18:44 满意答案 好评率...
  • 数据结构哈夫曼编码译码C语言
  • 设计一个哈夫曼编码译码系统。对一个文本文件中的字符进行哈夫曼编码,生成编码文件;反过来,可将编码文件译码还原为一个文本文件。
  • 数据结构哈夫曼编码译码功能,C语言版程序加完成版实验报告,完全可运,供大家参考。
  • 满意答案kitwz7752013.06.17采纳率:54%等级:12已帮助:8258人#include#include#includetypedef char ElemType;typedef struct{ElemType elem;unsigned int weight;unsigned int parent,lchild,rchild;...

    满意答案

    00e27ab806e4881f8254fe7ae8741834.png

    kitwz775

    2013.06.17

    00e27ab806e4881f8254fe7ae8741834.png

    采纳率:54%    等级:12

    已帮助:8258人

    #include

    #include

    #include

    typedef char ElemType;

    typedef struct{

    ElemType elem;

    unsigned int weight;

    unsigned int parent,lchild,rchild;

    }HTNode,*HuffmanTree;

    typedef char** HuffmanCode;

    typedef int Status;

    typedef struct {

    char elem;

    unsigned int weight;

    }Weight; // save the information of the symbolizes;

    void HuffmanCoding(HuffmanTree *,HuffmanCode *,Weight *,int);

    void Select(HuffmanTree,int,int *,int *);

    void OutputHuffmanCode(HuffmanTree,HuffmanCode,int);

    Status main(void)

    {

    HuffmanTree HT;

    HuffmanCode HC;

    Weight *w;

    char c;

    int i,n;

    int wei;

    printf("input the tatol number of the Huffman Tree:" );

    scanf("%d",&n);

    w=(Weight *)malloc(n*sizeof(Weight));

    for(i=0;i

    printf("input the element & its weight:");

    scanf("%1s%d",&c,&wei);

    w[i].elem=c;

    w[i].weight=wei;

    }

    HuffmanCoding(&HT,&HC,w,n);

    OutputHuffmanCode(HT,HC,n);

    return 1;

    }

    00分享举报

    展开全文
  • c语言实现的哈夫曼编码译码器,是数据结构中的经典案例。里面含有设计报告和源代码。把好的东西贡献出来,供大家参考一下。
  • C语言实现哈夫曼编码

    2020-08-19 06:25:11
    主要为大家详细介绍了C语言实现哈夫曼编码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 《数据结构C语言哈夫曼编码译码》由会员分享,可在线阅读,更多相关《数据结构C语言哈夫曼编码译码(16页珍藏版)》请在人人文库网上搜索。1、实训报告题 目: 哈夫曼树编码译码院 系: 信息工程系专 业: 计算机科学...

    《数据结构C语言哈夫曼编码译码》由会员分享,可在线阅读,更多相关《数据结构C语言哈夫曼编码译码(16页珍藏版)》请在人人文库网上搜索。

    1、实训报告题 目: 哈夫曼树编码译码院 系: 信息工程系专 业: 计算机科学与技术(网络方向)姓 名: 梁展荣 学 号: 指导教师: 赵莹莹 刘欣 日 期: 2013年7月3日 桂林电子科技大学信息科技学院目 录一、设计思想11.1建立哈夫曼树的思想11.2建立哈夫曼编码表21.3对文件进行编码21.4对文件进行解码2二、算法流程图3三、运行结果8四、遇到的问题及解决10五、心得体会13一、设计思想要完成哈夫曼的编码和解码需要首先建立哈夫曼树,之后对所有字符根据权重进行编码,最后再对文件内容进行编码和解码。1.1建立哈夫曼树的思想。首先定义适合哈夫曼树的节点类型,需要定义的有当前节点的字符,当前。

    2、节点的左子、右子和父亲指针。在建立哈夫曼树之前还需要对出现的字符和权重进行统计和记录,并且定义一个可以筛选出最小权重的函数。初始化树节点之后开始建立哈夫曼树。先在所有可能出现的字符中筛选出当前权重最小的两个字符,将这两个字符分别作为新节点的左子和右子建立一个小的二叉树,并将两个字符的权重之和赋值给新节点,将新二叉树放入筛选字符中,再将筛选过的两个字符从筛选列表中淘汰掉。依次对列表中剩下的字符进行权重最小的筛选,直到根节点(如果编码表共有N个字符,则2*N-1就为最终根节点)为止,也就是当筛选列表为空的时候,哈夫曼树即建立完成。对于哈夫曼编码树来说,由于哈夫曼编码是前缀码,所以所有要编码的字符最。

    3、终都将是这颗树的叶子节点,而其它节点并没有真正的字符意义。即当哈夫曼编码树建立之后,对树的所有叶子节点进行打印可知道是否有字符遗漏或多余。1.2建立哈夫曼编码表。建立编码表时要根据每个出现的字符的权重对建立的哈夫曼树的每个叶子节点进行编码。编码时要从叶子节点出发向根节点进行逆向编码。判断如果当前节点为左子则对其编码0,如果当前节点为右子则对其编码1。以此类推进行编码直到根节点为止。此时的编码是逆向的,所以需要将码值逆向存储。依次对每一个叶子节点进行编码操作,即可得到当前哈夫曼树的编码表。对于码值的逆向存储可以使用栈结构,先将一个码的每一步编码存入栈,再在一个码结束后出栈至空。当然也可以定义一个。

    4、字符型数组,将值从后向前存入数组,再将数组有值部分粘贴到新的数组中进行存储。本次采用了后者,因为个人认为为此一步操作建立栈结构不划算,而且前一个设计也已经熟练掌握了栈的方法,此处进行新的尝试会更好。1.3对文件进行编码。首先需要建立一个原始文件,在文件中输入需要编码的内容。之后将文件打开,将其中的内容存储到字符串中以便程序编码调用。开始对需要编码的字符进行编码,将字符逐一读取与刚刚建立的编码表中的每个叶子节点代表的字符进行比较,找出相同的对象,并将当前节点的编码打印到屏幕,并将编码存入到新建的密码文件当中。1.4对文件进行解码。先打开密码文件,将之前编码后得到的密文内容存储到字符串中以便解码调。

    5、用。开始对密文的字符串进行解码,树索引从根节点开始走,当密文中的当前字符是0的时候,则索引走向左子节点;当是1的时候,则走向右子节点。以此类推,一直走到叶子节点为止,则当前叶子节点所代表的字符即为前一段密文的解码结果,。再对下一个字符依次从根节点开始解码,如此循环对每一段密文进行解码直到解码结束。将解码打印到屏幕,并将解码结果存入到新的解码文件当中。在解码之前,还应该先确认之前是否建立了哈夫曼树并且是否构建了编码表。不过由于本次将a到z都进行了编码,所以此步省略了,因为编码表是唯一的。需要的时候可以在Encoder 函数中先进行判定。将编码和解码写在了一起,可以在运行时进行选择调用。二、算法流。

    6、程图第一步:建立哈夫曼树。图1建立哈夫曼树的算法流程图第二步:构建哈夫曼编码表。图2构建哈夫曼编码表的算法流程图第三步:编码。图3 编码算法流程图第四步:解码。图4 解码算法流程图四、运行结果原文文件:图5 中缀转后缀运行结果图编码图:图6 编码图密文文件:图7 密文文件图解码图:图8 解码图译文文件:图9 译文文件图整体运行图:图10 编码解码整体运行图五、遇到的问题及解决这部分我主要遇到了如下两个问题,其内容与解决方法如下所列:l 第一个问题是权重的筛选部分出现了错误解决办法:一开始对于筛选最小权重的代码编写如下:void SelectMin(HFMT T,int i,int *p1,in。

    7、t *p2) int j, min=999;for(j=0;jTj.weight)min=Tj.weight; *p1=j; min=999; for(j=0;jTj.weight&j!=(*p1)min=Tj.weight; *p2=j; 因为权重中最大的就是字符e的权重103,所以为初始值min赋值时觉得999就已经是无限大了。但是后来发现编码不知确,就开始思考是什么问题。发现每次筛选都将会把最小的两个权重进行相加,所以很快就会超过999,编码自然就出现了问题。所以后来将min定义成了long型,并赋值,问题就解决了。l 第二个问题是生成编码表的时候如何将逆向编码正向存储解决办法:对于求编。

    8、码的时候,由于是从叶子节点向根顺次而求,所以编码结果将是逆向的。一开始想到的办法是利用栈的结构,将编码依次存入栈中,再在一个字符编码结束时将栈倒空,这样就可以将编码正向存储了。但是又在考虑如果不用栈时候也可以做到。后来想到了strcpy函数对字符数组进行链接。所以就可以定义一个数组,从后向前存储编码,再在一个字符编码结束时将这个数组有值的重新存入新数组中,即可以成为正向编码了。最终实现编码如下:HFCode hfEn(HFMT T) int i,f,c,start;HFCode hc;char *cd;hc=(char *)malloc(N+1)*sizeof(char*); cd=(char。

    9、)malloc(N*sizeof(char); cdN-1=0; for(i=0;iN;i+) start=N-1;for(c=i,f=Ti.parent;f!=-1;c=f,f=Tf.parent)if(Tf.left=c) cd-start=0;else cd-start=1;hci=(char *)malloc(N-start)*sizeof(char); strcpy(hci,&cdstart); return hc;六、心得体会通过对本次的编写,使我掌握了哈夫曼编码的特点、存储方法和基本原理,培养了我运用C语言正确编写程序以及调试程序的能力。哈夫曼编码的结构取决于可能出现的字符的个数和其所对应的权值,权值大的编码短,权值小的编码长。这样的结构会利用比较小的空间存储数据。而且,利用树的结构对其编码和对其解码,也是比较规格话,比较方便的。本次编程还运用了结构体,便捷的对树节点和树以及编码表进行定义和调用。并且了解到当求解一个算法时,不是拿到问题就不假思索去做,而应该首先对它有个整体的概念,再一步步对其进行分析。在分析的过程中也应该学会随时总结问题,将遇到的问题融会贯通,以便在将来需要的时候能够应用自如。本次设计中也存在一些一开始不容易解决的问题,但当对算法的进一步分析和对相关信息的查阅,也比较顺利的完成了设计。虽然路途比较艰辛,但奋斗的经历却成为了最宝贵的人生经验。

    展开全文
  • 哈夫曼编码译码

    2017-12-29 23:10:39
    数据结构课程设计,实现哈夫曼编码译码,打印哈夫曼树
  • 按词频从小到大的顺序给出各个字符(不超过30个)的词频,根据词频构造哈夫曼树,给出每个字符的哈夫曼编码,并对给出的语句进行译码。 为确保构建的哈夫曼树唯一,本题做如下限定: (1)选择根结点权值最小的两棵...
  • 文章目录哈夫曼树及其应用哈夫曼树哈夫曼树的特点哈夫曼树的构造哈夫曼编码 哈夫曼树及其应用 哈夫曼树 介绍哈夫曼树前先介绍下面几个名词: 1. 结点的路径长度l 从根结点到该结点的路径上分支的数目,如下图结点a的...

    哈夫曼树及其应用

    哈夫曼树

    介绍哈夫曼树前先介绍下面几个名词:

    1. 结点的路径长度l

    从根结点到该结点的路径上分支的数目,如下图结点al = 3

    2. 树的路径长度

    树中所有叶子结点的路径长度之和,如下图该树的路径长度为2 + 3 + 3 + 2 + 2

    3. 结点的权w

    给每一个结点赋予一个新的数值,称为这个结点的权。

    4. 结点的带权路径长度l * w

    从根结点到该结点之间的路径长度与该结点的权的乘积,下图结点a的带权路径长度为l * w = 3

    5. 树的带权路径长度 WPL = ∑li * wi

    树中所有叶子结点的带权路径长度之和。


    带权路径长度WPL最小的二叉树称为哈夫曼树(又称为最优二叉树)。

    哈夫曼树的特点

    • 权值小的结点离根远,权值大的结点离根近。
    • 结点的度:没有度为1的结点。

    哈夫曼树的构造

    思路:

    1. 对于给定的有各自权值的n个结点,从n个权值中选出两个最小的权值,对应的两个结点组成一个新的二叉树,且新的二叉树的根结点的权值为左右孩子权值的和

    2. 在原有的n个权值中删除那两个最小的权值,同时将新的权值加入到n-2个权值的行列中,以此类推

    3. 重复1和2,直到所有的结点构建成了一棵二叉树为止,该树即为哈夫曼树。

    按权构造哈夫曼树的过程如下图

    哈夫曼编码

    一般地,设需要编码的字符集为{d1, d2, …… ,dn},各个字符在电文中出现的次数或频率集合为{w1, w2, …… , wn},以d1,d2,…… ,dn作为叶子结点,以w1,w2,…… ,wn作为相应叶子结点的权值来构造一棵哈夫曼树。规定哈夫曼树的左分支代表0,右分支代表1,则从根结点到叶子结点所经过的路径分支组成的0和1的序列便为该结点对应字符的编码,这就是哈夫曼编码。

    例如有一段文字内容"WINNIE WILL WIN"其中W的权值为3I的权值为4N的权值为3E的权值为1L的权值为2 ,则其按哈夫曼树规划如下。

    哈夫曼编码
    WINEL
    34312
    001110010011
    • 构造以W(3)I(4)N(3)E(1)L(2)为叶子结点的哈夫曼树
    • 将该二叉树所有左分枝标记0,所有右分枝标记1
    • 根结点到叶子结点所经过的二进制序列为该叶子结点字符的编码

    哈夫曼树结构

    /* 哈夫曼树结构 */
    typedef struct HTree
    {
        char data;
        int weight;
        int parent,leftChild,rightChild;
    } HTNode, *HuffmanTree;
    

    编码结构

    /* 编码结构 */
    typedef struct HCode
    {
        char data;
        char* str;
    } *HuffmanCode, HCode;
    

    统计字符和对应的次数

    /* 统计字符和对应的次数 */
    typedef struct wordcnt
    {
        char ch;
        int cnt = 0;
    } Count;
    
    /* 统计次数的外部封装 */
    typedef struct NumCount
    {
        Count count[MAXSIZE];
        int length = 0;
    } NumCount;
    

    读入文件

    /* 读入文件 */
    Status ReadData(char* source)
    {
        char ch;
        int i=0;
        FILE* pFile;
        pFile = fopen("myfile.txt","r");
        printf("正在读取文件\n");
        ch = fgetc(pFile);
        if(ch == EOF)
        {
            printf("文件为空\n");
            fclose(pFile);
            return ERROR;
        }
        fclose(pFile);
        pFile = fopen("myfile.txt","r");
        printf("文件内容是:");
        while ((ch = fgetc(pFile)) != EOF)
        {
            source[i++] = ch;
        }
        source[i] = '\0';
        printf("%s\n",source);
        fclose(pFile);
        return OK;
    }
    

    统计次数

    /* 统计次数 */
    Status WordCount(char* data, NumCount* tempCnt)
    {
        int flag;   //判断是否已经记录
        int len = strlen(data);
        for(int i = 0; i < len; ++i)
        {
            flag = 0;
            for(int j = 0; j < tempCnt->length; ++j)
            {
                if(tempCnt->count[j].ch == data[i]) //若已有记录,直接++
                {
                    ++tempCnt->count[j].cnt;
                    flag = 1;
                    break;
                }
            }
            if(!flag)   //若未记录,则新增
            {
                tempCnt->count[tempCnt->length].ch = data[i];
                ++tempCnt->count[tempCnt->length].cnt;
                ++tempCnt->length;
            }
        }
        return OK;
    }
    

    展示次数

    /* 展示次数 */
    Status Show(NumCount* tempCnt)
    {
        printf("长度为%d\n",tempCnt->length);
        for(int i = 0; i < tempCnt->length; ++i)
        {
            printf("字符%c出现%d次\n",tempCnt->count[i].ch,tempCnt->count[i].cnt);
        }
        printf("\n");
        return OK;
    }
    

    选中权值最小的两个结点

    /* 选中权重最小的两个结点 */
    Status select(HuffmanTree HT, int top, int* s1, int* s2)
    {
        int min = INT_MAX;
        for(int i = 1; i <= top; ++i)   //选择没有双亲的结点中,权重最小的结点
        {
            if(HT[i].weight < min && HT[i].parent == 0)
            {
                min = HT[i].weight;
                *s1 = i;
            }
        }
        min = INT_MAX;
        for (int i = 0; i <= top; ++i)  //选择没有双亲的结点中,权重次小的结点
        {
            if(HT[i].weight < min && i != *s1 && HT[i].parent ==0)
            {
                min = HT[i].weight;
                *s2 = i;
            }
        }
        return OK;
    }
    

    创建哈夫曼树

    /* 创建哈夫曼树 */
    Status CreateHuffmanTree(HuffmanTree &HT, int length, NumCount cntarray)
    {
        if(length <= 1)
            return ERROR;
        int s1,s2;
        int m = length * 2 - 1;   //没有度为1的结点,则总结点数是2 * 叶子结点数 - 1个
        HT = (HuffmanTree)malloc(sizeof(HTNode) * (m + 1));
        for (int i = 1; i <= m; ++i)    //初始化
        {
            HT[i].parent = 0;
            HT[i].leftChild = 0;
            HT[i].rightChild = 0;
        }
        
        for(int i = 1; i <= length; ++i)
        {
            HT[i].data = cntarray.count[i-1].ch;
            HT[i].weight = cntarray.count[i-1].cnt;
        }
        for(int i = length + 1; i <= m; ++i)
        {
            select(HT, i - 1, &s1, &s2);    //从前面的范围里选中权重最小的两个结点
            HT[s1].parent = i;
            HT[s2].parent = i;
            HT[i].leftChild = s1;
            HT[i].rightChild = s2;
            HT[i].weight = HT[s1].weight + HT[s2].weight;   //得到一个新结点
        }
        return OK;
    }
    

    创建哈夫曼编码

    /* 创建哈夫曼编码  */
    Status CreateHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int length)
    {
        HC = (HuffmanCode)malloc(sizeof(HCode) * (length + 1));
        char* cd = (char*)malloc(sizeof(char) * length);    //存储代码的临时空间
        cd[length-1] = '\0';    //方便之后调用strcpy函数
        int c,f,start;
        for(int i = 1; i <= length; ++i)
        {
            start = length-1;   //start表示编码在临时空间内的起始下标,由于是从叶子节点回溯,所以是从最后开始 
            c = i;
            f = HT[c].parent;
            while (f != 0)
            {
                --start;    //由于是回溯,所以从临时空间的最后往回计
                if(HT[f].leftChild == c)
                    cd[start] = '0';
                else
                    cd[start] = '1';
                c = f;
                f = HT[c].parent;
            }
            HC[i].str = (char*)malloc(sizeof(char) * (length - start)); // 最后,实际使用的编码空间大小是length-start
            HC[i].data = HT[i].data;
            strcpy(HC[i].str, &cd[start]);  // 从实际起始地址开始,拷贝到编码结构中 
        }
        free(cd);
    }
    

    将读入的文件编码写入txt文件

    /* 将读入的文件编码,写到txt文件  */
    Status Encode(char* data, HuffmanCode HC, int length)
    {
        FILE* pFile;
        pFile = fopen("mycode.txt","w");
        for(int i = 0; i < strlen(data); ++i)   //依次读入数据,查找对应的编码,写入编码文件
        {
            for(int j = 1; j <= length; ++j)
            {
                if(data[i] == HC[j].data)
                {
                    fputs(HC[j].str,pFile);
                }
            }
        }
        fclose(pFile);
        printf("编码文件已写入\n");
        return OK;
    }
    

    解码

    /* 读入编码文件,解码 */
    Status Decode(HuffmanTree HT,int length)
    {
        char* codetxt = (char*)malloc(sizeof(char)*(MAXSIZE*length));
        FILE* pFile;
        pFile = fopen("mycode.txt","r");
        fgets(codetxt, MAXSIZE*length, pFile);
        fclose(pFile);
    
        FILE* outfile;
        outfile = fopen("mytxt.txt","w");
        int root = 2*length - 1;    //从根结点开始遍历
        for(int i = 0; i < strlen(codetxt); ++i)
        {
            if(codetxt[i] == '0')
                root = HT[root].leftChild;  //为0表示向左遍历
            else if(codetxt[i] == '1')
                root = HT[root].rightChild; //为1表示向右遍历
            if(HT[root].leftChild == 0 && HT[root].rightChild ==0)  //如果已经是叶子结点,输出到文件中,然后重新返回到根结点
            {
                putc(HT[root].data,outfile);
                root = 2*length-1;
            }
        }
        fclose(outfile);
        printf("输出文件已写入\n");
        return OK;
    }
    

    完整代码

    #include <stdio.h> 
    #include <string.h>
    #include <stdlib.h>
    
    #define MAXSIZE 1024  // 读入文件的上限 
    #define OK 1
    #define ERROR 0
    typedef int Status;
    
    /* 统计字符和对应的次数 */
    typedef struct wordcnt
    {
        char ch;
        int cnt = 0;
    } Count;
    
    /* 统计次数的外部封装 */
    typedef struct NumCount
    {
        Count count[MAXSIZE];
        int length = 0;
    } NumCount;
    
    /* 哈夫曼树结构 */
    typedef struct HTree
    {
        char data;
        int weight;
        int parent,leftChild,rightChild;
    } HTNode, *HuffmanTree;
    
    /* 编码结构 */
    typedef struct HCode
    {
        char data;
        char* str;
    } *HuffmanCode, HCode;
    
    /* 读入文件 */
    Status ReadData(char* source)
    {
        char ch;
        int i=0;
        FILE* pFile;
        pFile = fopen("myfile.txt","r");
        printf("正在读取文件\n");
        ch = fgetc(pFile);
        if(ch == EOF)
        {
            printf("文件为空\n");
            fclose(pFile);
            return ERROR;
        }
        fclose(pFile);
        pFile = fopen("myfile.txt","r");
        printf("文件内容是:");
        while ((ch = fgetc(pFile)) != EOF)
        {
            source[i++] = ch;
        }
        source[i] = '\0';
        printf("%s\n",source);
        fclose(pFile);
        return OK;
    }
    
    /* 统计次数 */
    Status WordCount(char* data, NumCount* tempCnt)
    {
        int flag;   //判断是否已经记录
        int len = strlen(data);
        for(int i = 0; i < len; ++i)
        {
            flag = 0;
            for(int j = 0; j < tempCnt->length; ++j)
            {
                if(tempCnt->count[j].ch == data[i]) //若已有记录,直接++
                {
                    ++tempCnt->count[j].cnt;
                    flag = 1;
                    break;
                }
            }
            if(!flag)   //若未记录,则新增
            {
                tempCnt->count[tempCnt->length].ch = data[i];
                ++tempCnt->count[tempCnt->length].cnt;
                ++tempCnt->length;
            }
        }
        return OK;
    }
    
    /* 展示次数 */
    Status Show(NumCount* tempCnt)
    {
        printf("长度为%d\n",tempCnt->length);
        for(int i = 0; i < tempCnt->length; ++i)
        {
            printf("字符%c出现%d次\n",tempCnt->count[i].ch,tempCnt->count[i].cnt);
        }
        printf("\n");
        return OK;
    }
    
    /* 选中权重最小的两个结点 */
    Status select(HuffmanTree HT, int top, int* s1, int* s2)
    {
        int min = INT_MAX;
        for(int i = 1; i <= top; ++i)   //选择没有双亲的结点中,权重最小的结点
        {
            if(HT[i].weight < min && HT[i].parent == 0)
            {
                min = HT[i].weight;
                *s1 = i;
            }
        }
        min = INT_MAX;
        for (int i = 0; i <= top; ++i)  //选择没有双亲的结点中,权重次小的结点
        {
            if(HT[i].weight < min && i != *s1 && HT[i].parent ==0)
            {
                min = HT[i].weight;
                *s2 = i;
            }
        }
        return OK;
    }
    
    /* 创建哈夫曼树 */
    Status CreateHuffmanTree(HuffmanTree &HT, int length, NumCount cntarray)
    {
        if(length <= 1)
            return ERROR;
        int s1,s2;
        int m = length * 2 - 1;   //没有度为1的结点,则总结点数是2 * 叶子结点数 - 1个
        HT = (HuffmanTree)malloc(sizeof(HTNode) * (m + 1));
        for (int i = 1; i <= m; ++i)    //初始化
        {
            HT[i].parent = 0;
            HT[i].leftChild = 0;
            HT[i].rightChild = 0;
        }
        
        for(int i = 1; i <= length; ++i)
        {
            HT[i].data = cntarray.count[i-1].ch;
            HT[i].weight = cntarray.count[i-1].cnt;
        }
        for(int i = length + 1; i <= m; ++i)
        {
            select(HT, i - 1, &s1, &s2);    //从前面的范围里选中权重最小的两个结点
            HT[s1].parent = i;
            HT[s2].parent = i;
            HT[i].leftChild = s1;
            HT[i].rightChild = s2;
            HT[i].weight = HT[s1].weight + HT[s2].weight;   //得到一个新结点
        }
        return OK;
    }
    
    /* 创建哈夫曼编码  */
    Status CreateHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int length)
    {
        HC = (HuffmanCode)malloc(sizeof(HCode) * (length + 1));
        char* cd = (char*)malloc(sizeof(char) * length);    //存储代码的临时空间
        cd[length-1] = '\0';    //方便之后调用strcpy函数
        int c,f,start;
        for(int i = 1; i <= length; ++i)
        {
            start = length-1;   //start表示编码在临时空间内的起始下标,由于是从叶子节点回溯,所以是从最后开始 
            c = i;
            f = HT[c].parent;
            while (f != 0)
            {
                --start;    //由于是回溯,所以从临时空间的最后往回计
                if(HT[f].leftChild == c)
                    cd[start] = '0';
                else
                    cd[start] = '1';
                c = f;
                f = HT[c].parent;
            }
            HC[i].str = (char*)malloc(sizeof(char) * (length - start)); // 最后,实际使用的编码空间大小是length-start
            HC[i].data = HT[i].data;
            strcpy(HC[i].str, &cd[start]);  // 从实际起始地址开始,拷贝到编码结构中 
        }
        free(cd);
    }
    
    /* 将读入的文件编码,写到txt文件  */
    Status Encode(char* data, HuffmanCode HC, int length)
    {
        FILE* pFile;
        pFile = fopen("mycode.txt","w");
        for(int i = 0; i < strlen(data); ++i)   //依次读入数据,查找对应的编码,写入编码文件
        {
            for(int j = 1; j <= length; ++j)
            {
                if(data[i] == HC[j].data)
                {
                    fputs(HC[j].str,pFile);
                }
            }
        }
        fclose(pFile);
        printf("编码文件已写入\n");
        return OK;
    }
    
    /* 读入编码文件,解码 */
    Status Decode(HuffmanTree HT,int length)
    {
        char* codetxt = (char*)malloc(sizeof(char)*(MAXSIZE*length));
        FILE* pFile;
        pFile = fopen("mycode.txt","r");
        fgets(codetxt, MAXSIZE*length, pFile);
        fclose(pFile);
    
        FILE* outfile;
        outfile = fopen("mytxt.txt","w");
        int root = 2*length - 1;    //从根结点开始遍历
        for(int i = 0; i < strlen(codetxt); ++i)
        {
            if(codetxt[i] == '0')
                root = HT[root].leftChild;  //为0表示向左遍历
            else if(codetxt[i] == '1')
                root = HT[root].rightChild; //为1表示向右遍历
            if(HT[root].leftChild == 0 && HT[root].rightChild ==0)  //如果已经是叶子结点,输出到文件中,然后重新返回到根结点
            {
                putc(HT[root].data,outfile);
                root = 2*length-1;
            }
        }
        fclose(outfile);
        printf("输出文件已写入\n");
        return OK;
    }
    
    /* 测试 */
    void test()
    {
        char data[MAXSIZE];
        NumCount Cntarray;
        ReadData(data); //读入数据
        WordCount(data, &Cntarray); //统计次数
      //Show(&Cntarray);    //查看每个单词出现的次数
        HuffmanTree tree;
        CreateHuffmanTree(tree, Cntarray.length, Cntarray);   //建树
        HuffmanCode code;
        CreateHuffmanCode(tree, code, Cntarray.length); //创建编码
        Encode(data, code, Cntarray.length);    //生成编码文件
        Decode(tree, Cntarray.length);  //解码
        printf("请查看生成的TXT文件以检查结果\n");
        return ;
    }
    
    int main() 
    {
        test();
        return 0;
    }
    

    测试结果

    正在读取文件
    文件内容是:In love folly is always sweet
    
    I love three things in this world. Sun, moon and you. Sun for morning, moon for night , and you forever .
    
    "In fact, I am very satisfied at least know your name heard your voice to see your eyes."
    
    The furthest distance in the world. Is not being apart while being in love. But when plainly cannot resist the yearning. Yet pretending you have never been in my heart.
    
    编码文件已写入
    输出文件已写入
    请查看生成的TXT文件以检查结果
    
    myfile.txt

    mycode.txt(内容过长未截完)

    mytxt.txt

    展开全文
  • 哈夫曼编码c语言实现,代码中有注释。有编码和译码功能,能输出每个字符的Huffman码。可以输入一段Huffman码反应成文本,也可以输入一段文本翻译成Huffman码。计算了信源熵,编码效率,和平均编码长度。
  • C语言哈夫曼编码译码

    千次阅读 2022-01-05 09:31:42
    建立最优二叉树函数,实现哈夫曼树的编码译码系统,重复地显示并处理编码/解码功能,直到选择退出为止。自行选择存储结构,算法使用程序流程图表达;实现输出编码,并根据编码实现译码功能;采用菜单式交互操作,...
  • 该楼层疑似违规已被系统折叠隐藏此楼.../*动态分配数组,存储哈夫曼编码*/typedef struct{unsigned int weight ; /* 用来存放各个结点的权值*/unsigned int parent, LChild,RChild ; /*指向双亲、孩子结点的指针*/...
  • 用C++实现的哈夫曼编译码器,可以实现创建哈夫曼树、对txt文件进行编码译码,也可以查看生成的哈夫曼树。数据结构作业参考之必备品。
  • 7-2 哈夫曼编码译码

    千次阅读 2022-01-26 11:21:01
    编写一个哈夫曼编码译码程序。 按词频从小到大的顺序给出各个字符(不超过30个)的词频,根据词频构造哈夫曼树,给出每个字符的哈夫曼编码,并对给出的语句进行译码。 为确保构建的哈夫曼树唯一,本题做如下限定: ...
  • 简单实现哈夫曼编码译码过程,简单易懂` #include<stdio.h> #include<string.h> #include<stdlib.h> #include<conio.h> typedef struct{ char ch; //字符 int weight; //权值 int ...
  • 从键盘接收一串电文字符,输出对应的Huffman(哈夫曼)编码,同时,能翻译由Huffman编码生成的代码串,输出对应的电文字符串。设计要求: (1)构造一棵Huffman树; (2)实现Huffman编码,并用Huffman编码生成的代码...
  • 哈夫曼编码译码器数据结构C语言 一、需求分析 目前,进行快速远距离通信的主要手段是电报,即将需传送的文字转化成由二级制的字符组成的字符串。例如,假设需传送的电文为“ABACCDA”,它只有4种字符,只需两个字符...
  • 哈夫曼编码译码器.rar

    2020-07-11 15:53:03
    利用哈夫曼树生成最优编码,程序可以写文件,进而从写文件中再读取文件,然后对读取的文件进行哈夫曼编码,对文件进行编码,然后将编码文件存储成huf文件,然后再对huf文件进行译码译码后再将译码文件保存成txt...
  • 这个简单的小程序用C语言编写,实现了简单的哈夫曼编码译码,是通过文件操作实现的,数据结构很实用的代码,更好理解。
  • [题目] 哈夫曼编码/译码器 [需求描述] 利用哈夫曼编码进行通信可以提高信道利用率,缩短信息传输时间,降低传输成本。这要求在发送端通过一个编码系统对传输数据预先编码,在接收端将传来的数据进行译码,对于全双工...
  • 哈夫曼编码译码系统的实现,主要包含三部分:1、创建哈夫曼树2、编码函数3、译码函数编写代码时为了方便,在这里混用了c++的输入输出流。主体用c语言实现。下面是代码部分:1、头文件,以及储存结构:#include#...
  • 编写一个哈夫曼编码译码程序。 按词频从小到大的顺序给出各个字符(不超过30个)的词频,根据词频构造哈夫曼树,给出每个字符的哈夫曼编码,并对给出的语句进行译码。 为确保构建的哈夫曼树唯一,本题做如下限定: ...
  • 要求根据给定的权值,构建哈夫曼树,并实现哈夫曼编码译码。 直接上代码: #include<stdio.h> #include<malloc.h> #define maxval 10000.0 #define maxsize 100 //哈夫曼编码的最大位数 typedef ...
  • 哈夫曼编码译码器实验报告.rar

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 678
精华内容 271
关键字:

哈夫曼编码译码c语言