声明:凡代码问题,欢迎在评论区沟通。承蒙指正,一起成长!

目录

一、实验内容与要求

二、概要设计

三、直接上代码

四、运行结果


一、实验内容与要求

内容:哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法。其压缩率通常在20%~90%之间。哈夫曼编码算法用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式。
给出现频率高的字符较短的编码,出现频率较低的字符以较长的编码,可以大大缩短总码长。哈夫曼提出构造最优前缀码的贪心算法,由此产生的编码方案称为哈夫曼编码。哈夫曼算法以自底向上的方式构造表示最优前缀码的二叉树T。此算法以|c|个叶结点开始,执行|c|-1次的“合并”运算后产生最终所要求的树T。
要求:随机输入超过10字符及其频度,求出其这些字符的哈夫曼编码。

二、概要设计

1.定义哈夫曼树结点结构体类型;
2.以只读方式打开同文件夹下的“example.txt”,用指针申请动态字符数组tmp,并将文本读到字符串中;
3.哈夫曼树建立函数CrtHuffmanTree流程,(1)初始化:由给定的n个权值构造n棵只有一个根结点的二叉树,从而得到一个森林F;(2)选取与合并:利用select函数在F中选取根结点的权值最小的两棵二叉树分别作左、右子树构造一棵新的二叉树,这棵新的二叉树的根结点的主值为其左、右子树根结点的权值之和;(3)删除与并入:在集合F中删除作为左、右子树的两棵二叉树,并将新的二叉树加入到集合F中;(4)重复(2)、(3)两步,直到集合F中只剩下一棵二叉树时,便生成哈夫曼树;
4.哈夫曼编码建立函数CrtHutimanCode流程,(1)从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码;(2)分配求当前编码的工作空间,从右向左逐位存放编码;(3)求n个叶子结点对应的哈夫曼编码:初始化编码起始指针,从叶子结点开始向上倒推,左分支为0,右分支为1,向上倒推;(4)为编码分配空间,把编码cd[]复制到hc[i]中;
5.打印出26个字母在文本中出现的频度及编码,最后以哈夫曼编码形式打印出“example.txt”文本包括26个小写字母字符;

三、直接上代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MaxLeaf  26
#define MaxNode MaxLeaf*2-1
#define Maxbit  100typedef struct
{int weight;int parent;int LChild;int RChild;
} HTNode,HuffmanTree[MaxLeaf+1]; //结点结构体
typedef char * HuffmanCode[MaxLeaf+1];void CrtHuffmanTree(HuffmanTree ht,int w[],int n);//函数声明:建立哈夫曼树
void select(HuffmanTree ht,int n,int*x,int*y);//函数声明:寻找权值最小节点
void CrtHutimanCode(HuffmanTree ht,HuffmanCode hc,int n);//函数声明:生成哈夫曼编码
HuffmanTree ht;//树结点
HuffmanCode hc;//编码
int fre[MaxLeaf+1]= {0};
int main()
{int i;char name[20];printf("Please enter your File's name:");scanf("%s",&name);FILE *fp=fopen(name,"r");fseek(fp, 0, SEEK_END);int fileLen = ftell(fp);char *tmp = (char *) malloc(sizeof(char) * fileLen);fseek(fp, 0, SEEK_SET);fread(tmp, fileLen, sizeof(char), fp);fclose(fp);for(i = 0; i < fileLen-5; ++i){if((97<=tmp[i]<=122)&&tmp[i]!='.'&&tmp[i]!=','&&tmp[i]!=' '&&tmp[i]!='\n'&&tmp[i]!=':')fre[tmp[i]-96]+=1;}CrtHuffmanTree(ht,fre,MaxLeaf);CrtHutimanCode(ht,hc,MaxLeaf);printf("字符\t频度\t编码\n");for(i = 1; i <=26; ++i)printf("%c:\t%d\t%s\n",96+i,fre[i],hc[i]);printf("\nTXT文本的哈夫曼编码:\n");for(i = 0; i < fileLen-4; ++i){if((97<=tmp[i]<=122)&&tmp[i]!='.'&&tmp[i]!=','&&tmp[i]!=' '&&tmp[i]!='\n'&&tmp[i]!=':')printf("%s",hc[tmp[i]-96]);if(tmp[i]=='\n'||tmp[i]==' ')printf(" ");if(i!=0&&i%30==0)printf("\n");}printf("\n\n");/*for(i = 1; i <=MaxNode; ++i){printf("%d %d %d %d\t",ht[i].weight,ht[i].parent,ht[i].LChild,ht[i].RChild);if(i%3==0)printf("\n");}*/return 0;
}
void select(HuffmanTree ht,int n,int*x,int*y)
{int j,min1=2021,min2=2021;for(j=1; j<=n; j++)if((ht[j].parent==0)&(ht[j].weight<min1))/*找到第一个权值最小的根结点*/{min1=ht[j].weight;*x=j;}/*返回此结点的位置*/for(j=1; j<=n; j++)if(j!=*x&&ht[j].weight<min2&&ht[j].parent==0)/*找到第二个权值最小的根结点*/{min2=ht[j].weight;*y=j;}/*返回此结点的位置*/
}
void CrtHuffmanTree(HuffmanTree ht,int w[],int n)
{int i,s1,s2;for(i=1; i<=n; i++){ht[i].weight= w[i];ht[i].parent = 0;ht[i].LChild = 0;ht[i].RChild = 0;}int 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++) /*创建非叶结点,建哈夫曼树*/{select(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 CrtHutimanCode(HuffmanTree ht,HuffmanCode hc,int n)
{/*从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码*/char *cd;int i;cd=(char*)malloc(n*sizeof(char));cd[n-1]='\0';for(i=1; i<=n; i++){int start=n-1,c=i;int p=ht[i].parent;while(p!=0){/*从叶子结点开始向上倒推*/--start;if(ht[p].LChild==c) cd[start]='0';/*左分支标0*/else cd[start]='1';/*右分支标1*/c=p; p=ht[p].parent; /*向上倒推*/}hc[i]=(char*)malloc((n-start)*sizeof(char));/*为第1个编码分配空间*/strcpy(hc[i],&cd[start]);}free(cd);
}

四、运行结果

运行结果截图:

文本example.txt截图:

Huffman结构截图:

基于哈夫曼编码对txt文档实现压缩处理 | 算法分析之贪心算法设计 C语言版相关推荐

  1. 基于哈夫曼编码完成的文件压缩及解压

    这几天在较为认真的研究基于哈夫曼编码的文件压缩及解压,费了点时间,在这分享一下: 这里用链式结构,非顺序表结构: 文件压缩: 1.获取文件信息(这里采用TXT格式文本): 2.压缩文件: 3.写配置文 ...

  2. 基于哈夫曼编码对文件进行压缩和解压缩(详细讲解)

    基于哈夫曼编码对文件进行压缩和解压缩(详细讲解) 本文对应c++代码实现链接 一.背景 利用特定的算法来压缩数据的工具,压缩后生成的文件称为压缩包.如果想使用其中的数据,就得用压缩软件对数据进行解压. ...

  3. 使用哈夫曼编码实现txt文本的压缩(目前只支持英文文本)

    这是我第一尝试发帖子,有不足指出希望大家不吝指出和理解. 文本压缩效率 亲自测试,文本压缩效率大概在60%左右,是下载的英文版双城记.大概是198k可以压缩成121k左右的样子,当然压缩效率并不是绝对 ...

  4. python如何创建txt文档_基于python实现生成指定大小txt文档

    前言 在测试过程中经常遇到文件上传的功能,文件的大小边界值测试一直没有好的解决办法,这里我分享一个创建文件的脚本希望对大家有帮助. demo """ * Create b ...

  5. 哈夫曼编码实现文件的压缩和解压

    哈夫曼编码的概念 哈夫曼编码是基于哈夫曼树实现的一种文件压缩方式. 哈夫曼树:一种带权路径最短的最优二叉树,每个叶子结点都有它的权值,离根节点越近,权值越小(根节点权值为0,往下随深度增加依次加一), ...

  6. 哈夫曼树、哈夫曼编码与压缩比

    1.哈夫曼树 给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较 ...

  7. (王道408考研数据结构)第五章树-第四节3:哈夫曼树基本概念、构造和哈夫曼编码

    文章目录 一:哈夫曼树基本概念 (1)相关术语 (2)哈夫曼树定义 二:哈夫曼树的构造 三:哈夫曼树特点 四:哈夫曼树典型应用-哈夫曼编码 在计算机中, 文件压缩是一项非常重要的技术,它除了可以减少文 ...

  8. Qt实现哈夫曼编码解压缩软件详解

    目录 一.概要设计 二:设计效果展示: 三.源代码 1°MainWindow.h 2°MainWindow.cpp 3°Compression.h 4°Compression.cpp 四.软件分析 诸 ...

  9. 哈夫曼编码及文本文件的压缩解压(c++SourceCode)

    哈夫曼编码是一种编码方式,是可变字长编码(VLC)的一种.以哈夫曼树-即最优二叉树,带权路径长度最小的二叉树,经常应用于数据 压缩. 在计算机信息处理中,"哈夫曼编码"是一种一致性 ...

最新文章

  1. 记事本java代码_java实现Windows记事本(示例代码)
  2. Nearest Opposite Parity(反向建边+spfa)
  3. python中符号输入_Python基础(输入、运算符)
  4. stream流倒序排序_java8 stream多字段排序
  5. SQLi LABS Less 27 联合注入+报错注入+布尔盲注+时间盲注
  6. MySQL字符集的转换
  7. iOS 的TextView的常规用法
  8. 默认大小_如何更改 Linux 控制台字体类型和大小 | Linux 中国
  9. android开发常用的组件,Android开发常用控件与属性
  10. 使用SAXReader以XML方式解析excel
  11. c++的vector初始化
  12. 手机b站封面提取网站_二次元之家 视频网站B站上海与北京办公设计欣赏
  13. 【总结】漫画机器学习入门(大关真之著)
  14. 如何在 Android 上恢复删除屏幕截图/照片的四种方式
  15. 学大伟业:学长是如何对待数学竞赛的
  16. 一加7t人脸识别_一加7Pro和一加7TPro你发现什么异常?详细对比才发现这个问题!...
  17. Bunny's plan
  18. 喜报 | 40 under 40 杰出人才榜,Stratifyd 创始人兼CEO汪晓宇博士登榜
  19. freeline使用指南
  20. Deliveries(国际快递包裹跟踪软件)

热门文章

  1. MySQL 导入数据的几种方法
  2. Telnet登录、ssh登录
  3. 用python实现货币汇率的转换
  4. 携手英方软件,联想凌拓赋能数据新基建
  5. 分数/fractions模块的应用
  6. C++核心准则C.4:只有直接访问表达的函数,才应该成为成员
  7. scala字符串转int_如何在Scala中将十六进制字符串转换为int?
  8. python怎么将字符串变成int_在Python中,如何将字符串转换为int?
  9. LOCAL_CFLAGS用法
  10. java oa系统外部文件_java开发自动化办公OA系统