哈夫曼编码

为什么哈夫曼编码输出错误,有没有大神求解?

问题:

【问题描述】给定叶子结点的个数以及对应权值,构造哈夫曼树(序号小的做左子树),输出哈夫曼树对应的静态三叉链表;计算每个叶子结点的编码(左0右1)并输出。

【输入形式】输入叶子结点的个数以及对应权值。

【输出形式】显示结点序号,输出哈夫曼树的静态三叉链表(序号后面加冒号,静态三叉链表中元素之间用空格隔开,每个结点占一行);显示叶子结点的权值和对应的编码(叶子结点的权值后面加冒号,每个编码占一行)。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 5//叶子结点最大值
#define M 2 * N-1//所有结点最大值
typedef struct
{
    int weight;//结点权值
    int parent;//双亲下标
    int LChild;//左孩子结点下标
    int RChild;//右孩子结点下标
}HTNode,HuffmanTree[M+1];//HuffmanTree是一个结构数组类型0号单元不用*
typedef char * HuffmanCode[N+1];
void selects(HuffmanTree ht,int n,int *m1,int *m2)
{//找parent为0且权值最小的两个结点
    int i=1,temp;
    while(ht[i].parent>0)
        i++;
    *m1=i;
    i++;
    while(ht[i].parent>0)
        i++;
    *m2=i;
    i++;
    if(ht[*m1].weight>ht[*m2].weight)
    {
        temp=*m1;
        *m1=*m2;
        *m2=temp;
    }
    while(i<=n)
    {
        if(ht[i].parent==0)
        {
            if(ht[i].weight<ht[*m1].weight)
            {
                *m2=*m1;
                *m1=i;
            }
                else if(ht[i].weight<ht[*m2].weight)
                *m2=i;
        }
        i++;
    }
}
//创建哈夫曼树
void CrtHuffmanTree(HuffmanTree ht,int w[],int n)
{
    int s1,s2,i,m;
    for(i=1;i<=n;i++)
    {
        ht[i].weight=w[i];
        ht[i].parent=0;
        ht[i].LChild=0;
        ht[i].RChild=0;
    }
    m=2*n-1;
    for(i=n+1;i<=m;i++)
    {
        ht[i].weight=0;
        ht[i].parent=0;
        ht[i].LChild=0;
        ht[i].RChild=0;
    }
    for(i=n+1;i<=m;i++)
    {
        selects(ht,i-1,&s1,&s2);
        ht[i].weight=ht[s1].weight+ht[s2].weight;
        ht[s1].parent=i;
        ht[s2].parent=i;
        ht[i].LChild=s1;
        ht[i].RChild=s2;
    }
}
//哈夫曼编码
void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n)
{

    int i,c,p,start;
    char *cd;
    cd=(char*)malloc(n*sizeof(char));
    cd[n-1]='\0';
    for(i=1;i<=n;i++)
    {
        start=n-1;
        c=i;
        p=ht[i].parent;
        while(p!=0)
        {
            --start;
            if(ht[p].LChild==c) cd[start]='0';
            else
                cd[start]='1';
            c=p;
            p=ht[p].parent;
        }
        hc[i]=(char*)malloc((n-start)*sizeof(char));
        strcpy(hc[i],&cd[start]);
    }
    free(cd);
}
int main()
{
    int weight[N+1],i;
    for(i=1;i<=N;i++)
        scanf("%d",&weight[i]);
    HuffmanTree t;
    HuffmanCode code;
    CrtHuffmanTree(t,weight,N);
    printf("HuffmanTree is:\n");
    for(i=1;i<=2*N-1;i++)
        printf("%d:%d %d %d %d\n",i,t[i].weight,
               t[i].parent,t[i].LChild,t[i].RChild);
    CrtHuffmanCode(t,code,N);
     printf("The Code is:\n");
     for(i=1;i<=N;i++)
      printf("%d:%s\n",weight[i],code[i]);
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 哈夫曼编码是一种使用变长编码来减少数据传量的有效方法。在 Verilog 中,我们可以通过以下步骤实现哈夫曼编码。 首先,我们需要构建哈夫曼编码树。这棵树是由入数据的频率构建而成的。可以使用哈夫曼树构建算法,该算法会根据入数据的频率构造出最优的哈夫曼编码树。 然后,我们需要根据构建好的哈夫曼编码树生成对应哈夫曼编码表。哈夫曼编码表将字符与对应的二进制编码一一对应起来。可以使用深度优先搜索的方法遍历哈夫曼编码树,生成哈夫曼编码表。 接下来,我们可以编写 Verilog 代码来实现哈夫曼编码。首先,我们需要定义入数据的接口,并接收入数据。然后,根据入的字符,查询哈夫曼编码表,将对应的二进制编码出。 最后,我们需要将出的二进制编码进行传。为了正确传数据,我们需要在出数据前加入标志位,表示出数据的开始位置。在接收端,需要识别这个标志位,并将后续的二进制编码解码为对应的字符。 总结来说,哈夫曼编码在 Verilog 中的实现需要构建哈夫曼编码树,生成哈夫曼编码表,并编写相应的编码和解码逻辑。这样可以实现对入数据的高效压缩和解压缩。 ### 回答2: 哈夫曼编码是一种基于字符频率来构建编码的最优前缀编码方法。在Verilog中实现哈夫曼编码可以分为两步:构建哈夫曼树和生成编码表。 首先,构建哈夫曼树。我们可以使用二叉树的数据结构来表示哈夫曼树。在Verilog中,可以通过定义一个节点结构体来表示二叉树节点,其中包括字符和频率信息,以及右子节点指针。通过比较字符频率来构建哈夫曼树,可以采用贪心算法,每次选择频率最小的两个节点合并为一个新节点,直到只剩下一个节点为止。 接下来,生成编码表。通过遍历哈夫曼树,可以得到每个字符的编码。在Verilog中,可以使用递归或者迭代的方式进行树的遍历。当遍历到叶子节点时,记录下路径上的0和1,即可得到每个字符的哈夫曼编码。可以使用一个数据结构来保存字符与编码的对应关系,比如使用一个二维数组或者哈希表。 最后,将哈夫曼编码应用于实际数据压缩或传中。通过将原始数据按照对应的编码进行替换或者添加额外的标识,可以实现压缩和解压缩的功能。 总之,通过Verilog实现哈夫曼编码需要先构建哈夫曼树,然后生成编码表,最后将编码应用于数据压缩或传中。这是一个相对复杂的任务,需要熟悉Verilog语言和数据结构的相关知识才能完成。 ### 回答3: 哈夫曼编码是一种变长编码的压缩算法,常用于将频率较高的字符用较短的编码表示,从而减小存储或传的数据量。为了实现哈夫曼编码,可以使用硬件描述语言Verilog来设计相应的电路。 实现哈夫曼编码的Verilog电路需要以下几个主要模块: 1. 频率统计模块:用于统计入文本中各个字符的频率。入文本可以通过数据入端口传入,使用计数器来统计每个字符出现的次数。 2. 构建哈夫曼树模块:根据字符频率构建哈夫曼树。使用二叉堆等数据结构来优化树的构建过程,按照频率大小进行排序。 3. 哈夫曼编码生成模块:根据构建好的哈夫曼树,生成每个字符对应哈夫曼编码串。可以使用递归或者迭代的方式遍历哈夫曼树,同时记录每个字符的编码。 4. 编码器模块:将入的文本按照生成的哈夫曼编码进行编码。通过读取入文本的每个字符,并查找对应哈夫曼编码对应的编码串。 5. 译码器模块:将编码后的二进制串按照哈夫曼编码进行译码,得到原始文本。根据哈夫曼编码树进行译码,从根节点开始依次查找对应的字符。 以上模块可以通过组合逻辑电路来实现,可以利用状态机等技术进行控制。此外,还需要提供测试模块,用于验证设计的正确性。 总的来说,通过使用Verilog语言来设计实现哈夫曼编码的电路,可以实现对入文本进行压缩和解压缩的功能。这种硬件实现可以提高编码运行速度,并减小对系统资源的占用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值