哈夫曼编码与译码

哈夫曼树、哈夫曼编码与译码实现(c语言) 源于一次实验课,要求实现哈夫曼树、哈夫曼编码与译码;我就直接贴实验要求和代码实现了。 注:因为当时时间有限,故其实该代码还有优化空间,且输出文件是0/1字符串文本(UTF-8)并不是ASCII码编码文件,计算压缩率除以8即可。 实验项目:哈夫曼编码与译码方法 哈夫曼编码是一种以哈夫曼树(最优二叉树,带权路径长度最小的二叉 树)为基础的基于统计学的变长编码方式。其基本思想是:将使用次数多的代 码转换... 阅读详情
  1. 从文件中读入任意一篇英文文本文件,分别统计英文文本文件中各字符(包 括标点符号和空格)的使用频率;
  2. 根据已统计的字符使用频率构造哈夫曼编码树,并给出每个字符的哈夫曼编 码(字符集的哈夫曼编码表);
  3. 将文本文件利用哈夫曼树进行编码,存储成压缩文件(哈夫曼编码文件);
  4. 计算哈夫曼编码文件的压缩率;
  5. 将哈夫曼编码文件译码为文本文件,并与原文件进行比较。
  6. 利用堆结构,优化的哈夫曼编码算法
#include<stdio.h>
#include<stdlib.h>
#define MAXLEAF 50
#define MAXNODE 2*MAXLEAF-1
#define MAXWEIGHT 10000
#define MAXBIT 100
typedef struct character
{
    char ch;
    int count=0;
}CHARACTER;             //记录原文本文件中出现的字符及相应出现次数的类型
typedef struct hnodetype
{
    int weight;
    int parent;
    int lchild;
    int rchild;
    char value;
    int i;
}HNodeType;             //哈夫曼树的结点定义
typedef struct huffcodetype
{
    int bit[MAXBIT];
    int start;
}HCodeType;             //记录每个字符哈夫曼编码
typedef struct heap
{
    HNodeType node[MAXNODE+1];
    int n;
}HEAP;                  //最小堆的类型定义
void Statistic(CHARACTER chars[],int &n);                       //统计原文本中出现的字符及其使用频率
void Display(CHARACTER chars[],int n);                          //打印原文本中出现的字符及其使用频率
void CreateHT(HNodeType huffnode[],int n,CHARACTER chars[]);    //构建哈夫曼树
void Coding(HNodeType huffnode[],HCodeType huffcode[],int n);   //构建哈夫曼编码表
void Calculate(CHARACTER chars[],int n,int chnum);              //计算压缩率
void Display(HNodeType huffnode[],HCodeType huffcode[],int n);  //打印哈夫曼编码表
void CodingFile(HNodeType huffnode[],HCodeType huffcode[],int n,int &chnum);    //将文本编码并存入文件
void Decoding(HNodeType huffnode[],int n);                                      //将编码文件译码恢复

void Insert(HEAP &heap,HNodeType item);     //向堆里插入元素
HNodeType Delete(HEAP &heap);               //取堆顶元素并删除
void CreateHT_heap(HNodeType huffnode[],CHARACTER chars[],int n,HEAP &heap);    //用最小堆优化构建哈夫曼树的过程
int main()
{
    CHARACTER chars[MAXLEAF];
    HNodeType huffnode[MAXNODE];
    HCodeType huffcode[MAXLEAF];
    HEAP heap;heap.n=0;
    int n=0,chnum=0;
    Statistic(chars,n);
    Display(chars,n);
    //CreateHT_heap(huffnode,chars,n,heap);
    CreateHT(huffnode,n,chars);
    Coding(huffnode,huffcode,n);
    Display(huffnode,huffcode,n);
    CodingFile(huffnode,huffcode,n,chnum);
    Calculate(chars,n,chnum);
    Decoding(huffnode,n);
}
void Statistic(CHARACTER chars[],int &n)    //统计原文本中出现的字符及其使用频率
{
    FILE *f=NULL;
    if((f=fopen("original.txt","r"))==NULL)
    {
        printf("Fail to open original.txt!\n");
        exit(0);
    }
    char ch;
    int i=0,j=0,flag=0;;
    fscanf(f,"%c",&ch);
    chars[i].ch=ch;
    chars[i].count++;
    //printf("%c",chars[i].ch);
    i++;
    while(ch!='#')  //从文件读入文本,以#标记结束
    {
        fscanf(f,"%c",&ch);
        flag=0;
        if(ch!='#')
        {
            for(j=0;j<i;j++)
            {
                if(ch==chars[j].ch)  //如果读入的字符已被记录,则将出现次数+1
                {
                    chars[j].count++;
                    flag=1;
                    //printf("%c",chars[j].ch);
                    break;
                }
            }
            if(flag==0)
            {
                chars[i].ch=ch;
                chars[i].count++;
                //printf("%c",chars[i].ch);
                i++;
            }
        }
    }
    n=i;
    fclose(f);
}
void CreateHT(HNodeType huffnode[],int n,CHARACTER chars[])     //构建哈夫曼树
{
    int i,j,w1,w2,x1,x2;
    for(i=0;i<2*n-1;i++)        //初始化
    {
        huffnode[i].weight=chars[i].count;
        huffnode[i].parent=-1;
        huffnode[i].lchild=-1;
        huffnode[i].rchild=-1;
        huffnode[i].value=chars[i].ch;
    }
    for(i=0;i<n-1;i++)
    {
        w1=w2=MAXWEIGHT;
        x1=x2=0;
        for(j=0;j<n+i;j++)      //寻找权值最小的两个结点
        {
            if(huffnode[j].parent==-1&&huffnode[j].weight<w1)
            {
                w2=w1;
                x2=x1;
                w1=huffnode[j].weight;
                x1=j;
            }
            else if(huffnode[j].parent==-1&&huffnode[j].weight<w2)
            {
                w2=huffnode[j].weight;
                x2=j;
            }
        }
        huffnode[x1].parent=n+i;
        huffnode[x2].parent=n+i;
        huffnode[n+i].lchild=x1;
        huffnode[n+i].rchild=x2;
        huffnode[n+i].weight=w1+w2;
    }
}
void CreateHT_heap(HNodeType huffnode[],CHARACTER chars[],int n,HEAP &heap)  //利用堆优化哈夫曼树的构建
{
    int i;
    HNodeType node1,node2;
    for(i=0;i<2*n-1;i++)
    {
        huffnode[i].weight=chars[i].count;
        huffnode[i].parent=-1;
        huffnode[i].lchild=-1;
        huffnode[i].rchild=-1;
        huffnode[i].value=chars[i].ch;
        huffnode[i].i=i;
        if(i<n)
            Insert(heap,huffnode[i]);
    }
    for(i=0;i<n-1;i++)
    {
        node1=Delete(heap);
        node2=Delete(heap);
        huffnode[node1.i].parent=n+i;
        huffnode[node2.i].parent=n+i;
        huffnode[n+i].lchild=node1.i;
        huffnode[n+i].rchild=node2.i;
        huffnode[n+i].weight=node1.weight+node2.weight;
        huffnode[n+i].i=n+i;
        Insert(heap,huffnode[n+i]);
    }
}
void Coding(HNodeType huffnode[],HCodeType huffcode[],int n)        //构建字符的哈夫曼编码表
{
    HCodeType temp;
    int p,c;
    for(int i=0;i<n;i++)
    {
        huffcode[i].start=MAXBIT-1;
        c=i,p=huffnode[i].parent;
        while(p!=-1)
        {
            if(c==huffnode[p].lchild)
                huffcode[i].bit[huffcode[i].start]=0;
            else
                huffcode[i].bit[huffcode[i].start]=1;
            c=p;
            p=huffnode[p].parent;
            huffcode[i].start--;
        }
        huffcode[i].start++;
    }
}
void Display(HNodeType huffnode[],HCodeType huffcode[],int n) //打印哈夫曼编码表
{
    for(int i=0;i<n;i++)
    {
        printf("%c: ",huffnode[i].value);
        for(int j=huffcode[i].start;j<MAXBIT;j++)
        {
            printf("%d",huffcode[i].bit[j]);
        }
        printf("\n");
    }
}
void CodingFile(HNodeType huffnode[],HCodeType huffcode[],int n,int &chnum)     //对原文本编码并将编码写入文件
{
    FILE *fo=NULL;
    FILE *fc=NULL;
    if((fo=fopen("original.txt","r"))==NULL)
    {
        printf("Fail to open original.txt!\n");
        exit(0);
    }
    if((fc=fopen("compressed.txt","w"))==NULL)
    {
        printf("Fail to open compressed.txt!\n");
        exit(0);
    }
    char ch;
    do
    {
        fscanf(fo,"%c",&ch);
        if(ch!='#')
        {
            for(int i=0;i<n;i++)
            {
                if(huffnode[i].value==ch)
                {
                    for(int j=huffcode[i].start;j<MAXBIT;j++)
                    {
                        fprintf(fc,"%d",huffcode[i].bit[j]);
                        chnum++;
                    }
                }
            }
        }
    } while (ch!='#');
    fclose(fo);
    fclose(fc);
}
void Decoding(HNodeType huffnode[],int n)   //译码
{
    FILE *fc=NULL,*fd=NULL;
    if((fc=fopen("compressed.txt","r"))==NULL)
    {
        printf("Fail to open compressed.txt!\n");
        exit(0);
    }
    if((fd=fopen("decoding.txt","w"))==NULL)
    {
        printf("Fail to open decoding.txt!\n");
        exit(0);
    }
    char code[100000];
    fscanf(fc,"%s",code);
    int i=0,j=0,temp;
    for(i=0;code[i]!='\0';i++);
    while(j<i)
    {
        temp=2*n-2;
        while(huffnode[temp].lchild!=-1&&huffnode[temp].rchild!=-1)
        {
            if(code[j]=='0')
                temp=huffnode[temp].lchild;
            else
                temp=huffnode[temp].rchild;
            j++;
        }
        fprintf(fd,"%c",huffnode[temp].value);
    }
    fclose(fc);
    fclose(fd);
}
void Display(CHARACTER chars[],int n)   
{
    int total=0;
    double f=0;
    for(int i=0;i<n;i++)
    {
        total=total+chars[i].count;
    }
    for(int i=0;i<n;i++)
    {
        printf("frequency of %c is %f\n",chars[i].ch,chars[i].count*1.0/total);
    }
}
void Calculate(CHARACTER chars[],int n,int chnum)   //计算压缩率
{
    int total=0;
    for(int i=0;i<n;i++)
    {
        total+=chars[i].count;
    }
    printf("Compression rate is %f%%",chnum*1.0/8/total*100);
}
void Insert(HEAP &heap,HNodeType item)
{
    int i;
    if(heap.n<MAXNODE-1)
    {
        i=heap.n+1;
        while(i!=1&&item.weight<heap.node[i/2].weight)
        {
            heap.node[i]=heap.node[i/2];
            i/=2;
        }
        heap.node[i]=item;
        heap.n++;
    }
}
HNodeType Delete(HEAP &heap)
{
    int parent=1,child=2;
    HNodeType item,temp;
    if(heap.n>0)
    {
        item=heap.node[1];
        temp=heap.node[heap.n--];
        while(child<=heap.n)
        {
            if(child<heap.n&&heap.node[child].weight>heap.node[child+1].weight)
                child++;
            if(temp.weight<=heap.node[child].weight) break;
            heap.node[parent]=heap.node[child];
            parent=child;
            child*=2;
        }
        heap.node[parent]=temp;
        return item;
    }
}

测试数据与运行结果:
输入格式:输入一篇英文文本,以#结尾
输入:
在这里插入图片描述

各字符出现的频率:
在这里插入图片描述

在这里插入图片描述

字符集的哈夫曼编码表:

在这里插入图片描述
在这里插入图片描述

哈夫曼编码文件:

在这里插入图片描述

哈夫曼编码文件的压缩率:
在这里插入图片描述

译码结果:

在这里插入图片描述

C++实现哈夫曼编码/译码器(数据结构) 设计一个哈夫曼编码、译码系统。对一个ASCII编码的文本文件中的字符进行哈夫曼编码,生成编码文件;反过来,可将编码文件译码还原为一个文本文件。 (1) 从文件中读入任意一篇英文短文(文件为ASCII编码,扩展名为txt); (2) 统计并输出不同字符在文章中出现的频率(空格、换行、标点等也按字符处理); (3) 根据字符频率构造哈夫曼树,并给出每个字符的哈夫曼编码; (4) 图形化输出哈夫曼树、哈... 阅读详情

相关推荐

哈夫曼编码--英语文章的编码&译码(c/c++)

一.Huffman编码与解码 (Huffman编码、二叉树) [问题描述] 对一篇英文文章(大于2000个英文字符),统计各字符出现的次数,实现Huffman编码,以及对编码结果的解码。 [基本要求] (1) 输出每个字符出现的次数和编码,其中求最小权值要求用堆实现。 (2) 在Huffman编码后,要将编码表和英文文章编码结果保存到文件中,编码结果必须是二进制形式,即0 1的信息用比特位表示,不...

Y_xy_9的博客 1万+

C语言读取文件字符串统计字母个数

C语言读取文件字符串统计字母个数

weixin_54253218的博客 1934

数据结构——哈夫曼编码译码器

题目5: 哈夫曼编/译码器 [问题描述] 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼码的编/译码系统。 [基本要求] 一个完整的系统应具有以下功能: 1、I:初...

莉莉莉的博客 1万+

基于C++实现的哈夫曼编码文件加密系统

题目:文件加密系统完成功能:1.对密码本进行字符的统计,以及计算其权值,存储在线性表中。2.对二叉树结构修改为三叉树结构(森林),并利用1中的线性表建立三叉树结构形成012串,与文件中字符进行比对,生成文件编码Code.txt。(XX)3.对需要解密的文件以及密码本进行比对,解密并形成解密文件decode.txt4.前端界面以及选择功能。摘要在计算机技术突飞猛进的今天,加密程序的开发越来越受到开发者的青睐。本次数据结构课程设计选择文件加密系统,系统主要使用了哈夫曼编码技术,开发了一个对英文文本文件进行加密和

毕业作品网站 771

数据结构实训——哈夫曼编码/译码器

哈夫曼(Huffman)编/译码器(限1人完成) 【问题描述】 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼码的编/译码系统。首先输入一段包含27个字符(包含空格)...

Tang7O的博客 7265

unity 在透明物体上投射阴影

unity版本:2019.4.16 创建一个shader,代码如下: Shader "ChuckLee/ARShadow" { Properties { _ShadowColor("Shadow Color", Color) = (0.1, 0.1, 0.1, 0.53) } SubShader { Tags{ "RenderType" = "Transparent" "Queue" = "Geometry+1" } Blend SrcAlpha OneMinusSrcAlph

Abel02的博客 2953

哈夫曼编码译码(数据结构课程设计)

1.需求分析 1.1问题描述 设计一个利用哈夫曼算法的编码和译码系统,重复地显示并处理以下项目,直到选择退出为止。 1.2 基本要求 将权值数据存放在数据文件(文件名为data.txt,位于执行程序的当前目录中)  分别采用动态和静态存储结构 初始化:键盘输入字符集大小n、n个字符和n个权值,建立哈夫曼树; 编码:利用建好的哈夫曼树生成哈夫曼编码; 输出编码; 设字符集及频度如下

u011710873的专栏 2万+

深入解析DMR协议中的4-CPFSK调制技术与实现

本文深入解析了DMR协议中采用的4-CPFSK调制技术。该技术凭借其连续相位、恒包络的特性,在有限的12.5kHz信道带宽内实现了稳健的通信,有效对抗干扰并提升功放效率,是DMR数字对讲机清晰、稳定通信的核心保障。文章详细阐述了其原理、实现细节及在协议栈中的协同作用。

weixin_29306875的博客 229

哈夫曼编码/译码器

这次课程设计的心得体会通过实践我的收获如下:① 巩固和加深了对数据结构的理解,提高综合运用本课程所学知识的能力。② 培养了我选用参考书,查阅手册及文献资料的能力。培养独立思考,深入研究,分析问题、解决问题的能力。③ 通过实际编译系统的分析设计、编程调试,掌握应用软件的分析方法和工程设计方法。④ 通过课程设计,培养了我严肃认真的工作作风,逐步建立正确的生产观念、经济观念和全局观念。根据我在实习中遇到得问题,我将在以后的学习过程中注意以下几点:① 认真上好专业实验课,多在实践中锻炼自己。

Bit_Dong的博客 1万+

智能车竞赛模糊PID代码与使用方法

本文给出了模糊PID的代码,以及模糊PID的程序使用方法、参数调整方法

piginthesouth的博客 9123

【Basis】Lumerical licence center 无法连接的问题

端口,我们需要确认该端口是否被其他程序占用。这里我们将介绍如何处理这一问题。后,今天电脑更新后我无法打开。终结占用该端口的程序后再次打开。

u011699626的博客 313

哈夫曼编码译码

题目 编写一个哈夫曼编码译码程序。 按词频从小到大的顺序给出各个字符(不超过30个)的词频,根据词频构造哈夫曼树,给出每个字符的哈夫曼编码,并对给出的语句进行译码。 为确保构建的哈夫曼树唯一,本题做如下限定: (1)选择根结点权值最小的两棵二叉树时,选取权值较小者作为左子树。 (2)若多棵二叉树根结点权值相等,按先后次序分左右,先出现的作为左子树,后出现的作为右子树。 生成哈夫曼编码时,哈夫曼树左分支标记为0,右分支标记为1。 【输入格式】 第一行输入字符个数n; 第二行到第n行输入相应的字符及其权值;

qq_44769557的博客 8441

某智能物流无人值守系统 ExportReport SQL注入漏洞复现

某智能物流无人值守系统 ExportReport存在SQL注入漏洞,未经身份验证的远程攻击者除了可以利用 SQL 注入漏洞获取数据库中的信息(例如,管理员后台密码、站点的用户个人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限。

0xSec 818

哈夫曼编码和译码的实现

哈夫曼编码和译码的实现 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; /*哈夫曼树的应用----哈夫曼编码*/ //哈夫曼树的结点结构 typedef struct HuffmanTree{ in...

qq_42932834的博客 2181

8、水力压裂引起的地质材料力学性质变化的可视化研究

本研究探讨了水力压裂引起的地质材料力学性质变化的可视化方法。利用超声剪切波形数据,通过短时傅里叶变换(STFT)和主成分分析(PCA)进行特征提取和降维,并应用K-means聚类、凝聚聚类和DBSCAN等无监督学习方法对地质力学变化进行非侵入式可视化分析。研究比较了不同特征工程、聚类方法和降维策略对可视化效果的影响,并结合位移不连续性理论为聚类结果分配地质力学变化指数,以提高结果的物理解释性。最终,该方法成功实现了对水力压裂引起的岩石力学性质变化的高效、可靠可视化。

emacs5lisp的博客 109

21、使用 FastHenry 进行片上电感器的模拟与参数预测

本文介绍了使用 FastHenry 对片上电感器进行模拟和参数预测的方法。讨论了 FastHenry 的适用场景、线圈几何形状的选择与离散化方法,以及如何考虑模拟中的寄生效应。同时对比了 FastHenry 和 Magnet 在不同基板电阻率下的模拟精度,并提出了优化电感器设计的策略,为高效准确地预测电感参数提供了技术指导。

y9z0a1b的博客 292

【数据结构课程设计】哈夫曼编码译码的设计与实现

问题描述和求解方法:首先根据给定的n个字符的权值构造哈夫曼树。通过遍历此二叉树完成各字符的哈夫曼编码,另输入一组‘0’、‘1’代码构成的报文将其翻译成对应的字符信息。

DUMG 1万+

华为OD新系统机试真题 - 获取大写字母瓷砖拼出独特图案数量

华为OD机试新系统真题【获取大写字母瓷砖拼出独特图案数量】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD新系统四月二十九号机试真题【获取大写字母瓷砖拼出独特图案数量】

qq_45776114的博客 1218

JAVA实现哈夫曼编码与译码

如题哈夫曼基本思想百度说的更好,在此不做赘余,直接上实现思路与具体代码。1.先实现哈夫曼树的基础  节点 以及 编码 (假设树已经建好)public class node { String rode =""; node left = null; node right = null; int value=1; char c; node (){} node (char c)...

nihongyeyu的博客 6669

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

7-2 哈夫曼编码译码

编写一个哈夫曼编码译码程序。 按词频从小到大的顺序给出各个字符(不超过30个)的词频,根据词频构造哈夫曼树,给出每个字符的哈夫曼编码,并对给出的语句进行译码。 为确保构建的哈夫曼树唯一,本题做如下限定: (1)选择根结点权值最小的两棵二叉树时,选取权值较小者作为左子树。 (2)若多棵二叉树根结点权值相等,按先后次序分左右,先出现的作为左子树,后出现的作为右子树。 生成哈夫曼编码时,哈夫曼树左分支标记为0,右分支标记为1。 输入格式: 第一行输入

qq_51472701的博客 4369

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

哈夫曼编码译码系统

文章目录实验目的实验设备与环境实验过程及结果分析1. 构造哈夫曼树2. SelectSmall函数3. 哈夫曼编码4. 哈夫曼译码5. 实验结果实验代码main.cppHuffman.h 实验目的 完成Huffman Tree 编码、译码系统的设计 自行设计测试数据 自行找一段本文,统计本文中每一个字符出现的频率。 理解建立Huffman Tree(编码)过程 实验设备与环境 Dev-C++ 5.11 实验过程及结果分析 1. 构造哈夫曼树 设已知n个结点的权值,根据这些权值构成森林F,森林中的每棵二

Teemos的博客 2453

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

哈夫曼编码译码器

标题数据结构课设:哈夫曼编码译码器 总结一下这次的课程设计,遇到的问题是如何解决的。 功能: 将权值数据存放在数据文件data.txt中。 键盘输入字符集大小n、n个字符和n个权值,建立哈夫曼树。 利用建好的哈夫曼树生成哈夫曼编码。 使用data.txt中的权值数据生成的哈夫曼编码,将文件Text.txt中的字符串编码保存到HuffmanCode.txt文件中。 使用data.txt中的权值数据...

ljinshuo的博客 5878

哈夫曼编码/译码的设计与实现

首先根据给定的n个字符的权值构造哈夫曼树。通过遍历此二叉树完成各字符的哈夫曼编码,另输入一组‘0’、‘1’代码构成的报文将其翻译成对应的字符信息。 废话不说直接上代码: #include #include #define UINT_iMAX 10000 using namespace std; typedef struct { char letter, *code; int weig

奋斗在路上 3万+
上一篇: 迪杰斯特拉算法——堆优化
下一篇: PTA7-2一元多项式的乘法与加法运算
TC_Ning
博客等级 码龄6年 21粉丝 13原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值