HuffmanTre----文件压缩

1)首先是哈弗曼树的原理:
如果有一些结点的权值分别是1,2,3,4,5,6
那么它们构建出来的哈弗曼树是什么样子呢?
结果如图:

思想是每次从数组中取两个当前权值最小的数去创建结点,并作为叶子结点,它们的根节点的权值是两者之和,把它再放回数组,第一次选择1,2;第二次选择3,3;第三次选择4,5;~~~~
2)哈弗曼树的构建:
因为要每次选择最小的两个数,自然想到要用堆啦~堆的代码以前实现过的,直接头文件加进来用,但是问题就来了,这里要用小堆,所以要用<,
堆里面是结点,可要比较的是结点的权值大小,以前实现的堆对直接用堆里面的数据去比较大小的,所以就要去重写一下传到堆里面的那个仿函数啦~
3)文件压缩的原理:
哈弗曼树建好,现在要正式开始文件压缩啦~
文件压缩真正要用到的是哈夫曼编码,还是刚才那棵树,它的哈弗曼编码怎么来的呢?

权值为1的结点的哈夫曼编码就是1000
权值为2的结点的哈夫曼编码就是1001
权值为3的结点的哈夫曼编码就是101
权值为4的结点的哈夫曼编码就是00
权值为5的结点的哈夫曼编码就是01
权值为6的结点的哈夫曼编码就是11
哈夫曼编码只是对叶子节点编码哦~~~
可以发现一个规律就是权值越小的,它的哈夫曼编码越长,权值越大的,哈夫曼编码越短。
那么如何运用到文件压缩中呢?
举一个简单的例子吧,假设有一个文件的内容是“abbcccdddd“,‘a’出现的次数是1,‘b’出现的次数是2,‘c’出现的次数是3,‘d’出现的次数是4,以各字符出现的次数构建一个哈夫曼树,并为各字符编码,结果是:
‘a’:100;  ‘b’:101;  ‘c’:11;  ‘d’:0;
以编码的形式按照原字符的顺序写入压缩文件,就应该是这样滴:
1001011011111110000
这一个0或1代表一个二进制位,那压缩文件是多大呢?3个字节
原文件是多大呢?10个字节
这就是文件压缩的原理。
4)文件压缩的过程:
根据上面的例子,首先要统计待压缩文件中各字符出现的次数,然后构造哈弗曼编码,把编码写入压缩文件,不够一个字节的就在后面补零,因为还要解压缩,所以还得写一个配置文件,配置文件里面写每个字符出现的次数。
5)文件解压缩的过程:
先去读配置文件,构建哈弗曼树和哈弗曼编码,用压缩文件里的编码去哈弗曼树里面找,找到叶子结点,就把叶子节点的字符写入解压缩文件中。
项目测试:通过Beyond Compare对文件压缩前和压缩后的内容进行比对,验证程序的正确性。
6
)性能测试,一个25M左右的大文件,在Debug版本下压缩的时间大约为30s,解压缩时间大约为10s,压缩文件的大小为20M左右;一个6k左右的
小文件在Debug版本下压缩的时间大约为30ms,解压缩时间大约为30ms,压缩文件的大小为3.5K左右;在release版本下会更高效一些,时
间会缩短很多。

再说说项目过程中出现的问题的问题吧,我测试的时候发现如果待压缩文件中出现中文,程序就会崩溃,将错误定位到构造哈弗曼编码的函数处,通过单步调
试发现是数组越界所致,终于明白是为什么了,如果只是字符的话,它的范围是0~127,程序中通过一个char类型的变量作为数组的下标,是没有问题的,
但汉字的编码是两个字节,所以会发生数组越界,解决方法是将char强转为unsigned char。

时间: 2024-08-06 11:58:33

HuffmanTre----文件压缩的相关文章

iOS网络-ZipArchive框架的文件压缩和解压

导入第三方框架ZipArchive之后还要在系统库文件中导入一个如下文件(搜索libz出来的任何一个都可以) 文件压缩 -(void)zip { NSArray *arrayM = @[@"/Users/gengqun/Desktop/Snip20160118_866.png", @"/Users/gengqun/Desktop/Snip20160118_867.png", @"/Users/gengqun/Desktop/Snip20160118_868

Linux下的文件压缩和打包

Linux 上的压缩包文件格式,除了 Windows 最常见的*.zip.*.rar..7z后缀的压缩文件,还有 .gz..xz..bz2..tar..tar.gz..tar.xz.tar.bz2 文件后缀名                               说明 *.zip                       zip程序打包压缩的文件 *.rar                          rar程序压缩的文件 *.tar                     tar

grunt-js文件压缩

grunt常用函数说明: Grunt : javascript世界的构建工具. grunt.initConfig : 定义各种模块的参数,每个成员项对应的一个同名模块. grunt.loadNpMTasks : 加载完成所需要的模块. grunt.registerTask : 定义具体的任务.第一个参数为任务名.第二个参数是一个数组,表示该任务需要一次使用的模块. 用于模块配置,它接受一个对象作为参数.该对象的成员与使用的同名模块--对应. (js文件压缩代码) // Project confi

php 文件压缩

PclZip文件压缩实现(推荐) 我在做项目是的时候有个打包下载的需求:把上传的多个文件压缩成一个文件并下载,我用的比较强大的PclZip类实现的.我的用的是thinkphp3.2框架开发的,具体实现代码如下  /**     * 压缩文件     * @param $zipName  压缩的文件名     * @param $fileName 要压缩的文件路径的数组或字符串     *  @param  $savePath  要保存的路径     * @return bool     */ p

使用VisualStudio进行脚本|样式文件压缩

在vs的Optimization中有个Bundle是专门用来压缩样式和脚本文件 .他有两个继承:StyleBundle.ScriptBundle,从名字上就可看出,StyleBundle专门压缩样式文件.ScriptBundle专门压缩脚本文件. 在App_Start文件夹下,写出BundleCollection,添加需要压缩的文件名 注意:在这里对压缩文件合并而路径名,会产生虚拟路径,可以在浏览器监控中看到.虚拟路径不能和真实路径一样,如果一样程序会找真实路径,压缩会不成功. 将压缩路径引用在

Linux学习笔记&lt;十三&gt;——文件压缩、解压缩和归档

压缩.解压缩命令: 1.compress/uncompress:压缩格式为Z,文件后缀为.Z compress /path/to/file uncompress /path/to/file.Z 2.gzip/gunzip/zcat:压缩格式为gz,文件后缀为.gz gzip [OPTION] /path/to/file:,压缩文件保存在被压缩文件的目录,压缩完成后会删除原文件 -v|verbose:显示指令执行过程 -d:解压缩,解压缩完成后删除原压缩文件 -#:1-9,指定压缩比,默认为6,数

前端部署ant+yuicompressor文件压缩+获取版本号+SSH发布(部分代码)

文件压缩: <apply executable="java" parallel="false" failonerror="true" dest="../../release/publish/ecshop" append="false" force="true"> <fileset dir="../../release/publish/ecshop"&

基于哈夫曼编码的文件压缩(c++版)

本博客由Rcchio原创 我了解到很多压缩文件的程序是基于哈夫曼编码来实现的,所以产生了自己用哈夫曼编码写一个压缩软件的想法,经过查阅资料和自己的思考,我用c++语言写出了该程序,并通过这篇文章来记录一下自己写该程序学到的东西.因为本人写的程序在压缩率上,还有提升的空间,所以本文将不定期更新,但程序整体的思路不会有较大的改动. 一.基于哈夫曼编码可实现压缩文件的原理分析 在计算机中,数据的存储都是二进制的,并且以字节作为基本的存储单位,像英文字母在文本中占一个字节,汉字占两个字节,我们把这种每一

Huffman的应用之文件压缩与解压缩

文件压缩与解压缩> 最近这段时间一直在学习树的这种数据结构,也接触到了Huffman树以及了解了什仫是Huffman编码,而我们常用的zip压缩也是利用的Huffman编码的特性,那仫是不是可以自己实现一个文件压缩呢?当然可以了.在文件压缩中我实现了Huffman树和建堆Heap的代码,zip压缩的介绍> http://www.cricode.com/3481.html 下面开始介绍自己实现的文件压缩的思路和问题... 1).统计>读取一个文件统计这个文件中字符出现的次数. 2).建树&

关于linux系统下文件压缩归档操作命令略提

Linux下文件压缩归档操作命令:gzip/ungzip 后缀 .gz  xz/unxz       后缀 .xz  bzip2/bunzip2 后缀 .bz2  tar 用于归档并压缩  -# :#为0-9 指定压缩比 gzip -c name 压缩结果输出到标准输出  -d 解压缩  -v verbose  zcat 不解压的情况下查看压缩文件  -r 递归压缩 xz -k 保留原文件 xzcat 不解压的情况下查看原文件 tar Jcf FILE.tar.xz /DIR/TO/FILE 将