`
Coco_young
  • 浏览: 127627 次
  • 性别: Icon_minigender_1
  • 来自: 湖南长沙
社区版块
存档分类
最新评论

哈弗曼编码以及用其实现压缩软件

阅读更多

1.什么是哈夫曼树?

   哈夫曼树是一种最优二叉树,它的最优点体现在它的的带权路径长度最小。(结点的带权路径长度为:结点的路径长度乘以结点的权值,树的带权路径长度为所有叶子结点带权路径长度之和)

2.什么是哈弗曼编码?

   从哈弗曼树的根结点开始,按照左子树分配代码“0”,右子树分配代码“1”的规则,直到叶子结点为止,每个叶子结点的哈弗曼编码就是从根结点开始,一直到该叶子结点为止,把途中经过的代码按顺序串起来就OK了。



 

3.什么是哈弗曼压缩?

     Huffman( 哈夫曼 ) 算法在上世纪五十年代初提出来了,它是一种无损压缩方法,在压缩过程中不会丢失信息熵,而且可以证明 Huffman 算法在无损压缩算法中是最优的。 Huffman 原理简单,实现起来也不困难,在现在的主流压缩软件得到了广泛的应用。对应用程序、重要资料等绝对不允许信息丢失的压缩场合, Huffman 算法是非常好的选择。

      哈夫曼压缩,一般用来压缩文本和程序文件。哈夫曼压缩属于可变代码长度算法一族。意思是个体符号(例如,文本文件中的字符)用一个特定长度的位序列替代。因此,在文件中出现频率高的符号,使用短的位序列,而那些很少出现的符号,则用较长的位序列。

 

有了以上的基本概念,我们就可以动手实现哈弗曼压缩软件了!

 

4.哈弗曼压缩软件的实现:

   在文件中,所有的数据都是以字节的形式存在的,一个字节是8位,所以所有可能出现的字节在0——256之间(不包括256),所以,第一步要做的事情就是,把文件所有的字节的出现频率统计出来,并用频率做为权值生成一棵哈弗曼树:

   

int[] ByteCount = new int[256];//字节频率统计
		
		InputStream fis = new FileInputStream(pathName_former);		
		InputStream bis = new BufferedInputStream(fis);//创建文件输入流
		
		while(bis.available()>0){
			int tmp = bis.read();
			ByteCount[tmp]++;
		}//统计频率
		
		//构造哈弗曼树
		hfmTree hfm = new hfmTree(ByteCount);

 

public hfmTree(int[] rank){//根据频率构造哈弗曼树

		//把频率不为零的字节加入节点优先级队列
		PriorityQueue<hfmNode> nodes = new java.util.PriorityQueue<hfmNode>();
		
		for(int i=0;i<rank.length;i++){
			if(rank[i]!=0){
				nodes.add(new hfmNode(rank[i],i));
			}
		}
		//构造哈弗曼树
		while(nodes.size()!=1){
			hfmNode node_1 = nodes.poll();//1
			hfmNode node_2 = nodes.poll();//2
			hfmNode addNode = new hfmNode(node_1.getRank()+node_2.getRank(),0);
			addNode.setLeft(node_1);
			addNode.setRight(node_2);
			nodes.add(addNode);
		}
		
		root = nodes.poll();
		
		
	}//构造函数(correct)

 

 

 

 

 接下来,要做的就是获得0——256之间每个字节所对应的哈弗曼编码,用一个String[] Code = new Code[256]保存  下来

//获得编码
	private void getStrByte(hfmNode node,String s){
		if(node.getLeft()==null&&node.getRight()==null){
			Code[node.getData()] = s;//获得编码字符串
		}
		if(node.getLeft()!=null){
			getStrByte(node.getLeft(),s+"0");
		}//左零
		if(node.getRight()!=null){
			getStrByte(node.getRight(),s+"1");
		}//右1
	}

 

 然后就是把每个字节的编码长度打入文件:

 

//先将0-255的编码长度打到文件里
		for(int i=0;i<Code.length;i++){
			if(Code[i]==null||Code[i]==""){
				Code[i] = "";
				bos.write(0);
			}else{
				bos.write(Code[i].length());
			}
		}

 

接下来就是,将每个字节的编码打入文件(这里需要吧8个长度的01串转换成一个byte打入文件):

  

//把每个字节的编码表打到文件里
		int i = 0;//第i个字节
		int count = 0;//满8打一,计数器
		String writeCode = "";//写入的8位编码
		String allCode = "";//所有待写入的编码
		String inCode = "";
		while(i<256||count>=8){
			if(count>=8){//满8
				writeCode = allCode.substring(0,8);//前8位
				count-=8;
				allCode = allCode.substring(8);
				bos.write(changeString(writeCode));//写入一个字节
			}else{
				count+=Code[i].length();
				allCode+=Code[i];
				inCode+=Code[i];
				i++;//严重错误发生地
			}
		}
		//如果不满8位的
		if(allCode.length()>0){
			int len = 8-allCode.length();//补零
			for(int j=0;j<len;j++){
				allCode+="0";
			}
			inCode+=allCode;
			bos.write(changeString(allCode));
		}

 最后就是把文件中的所有字节按照这种哈弗曼的编码方式保存到文件中,过程类似于上一步(在最后打入末尾补入的0的个数,主要是为了方便解压缩):

  

//编码表输出完毕,将文件中的字节按照这种编码方式压缩
		InputStream ins = new FileInputStream(pathName_former);
		InputStream buf = new BufferedInputStream(ins);//创建输入流
		count = 0;
		writeCode = "";
		allCode = "";
		
		while(buf.available()>0||count>=8){
			if(count>=8){//满8
				writeCode = allCode.substring(0,8);//前8位
				count-=8;
				allCode = allCode.substring(8);
				bos.write(changeString(writeCode));//写入一个字节
			}else{
				int data = buf.read();
				count+=Code[data].length();
				allCode+=Code[data];
			}
		}
		//如果不满8位的
		if(allCode.length()>0){
			int len = 8-allCode.length();//补零
			for(int j=0;j<len;j++){
				allCode+="0";
			}
			bos.write(changeString(allCode));
			bos.write(len);//补入了几个0
		}else{
			bos.write(0);//补入了0个0
		}

 到这里,整个压缩过程基本完成了,解压缩就是压缩的逆过程,在此不再赘述,所有的操作都保存在附上源代码中。

  • 大小: 15 KB
3
4
分享到:
评论

相关推荐

    用哈弗曼编码对文件进行压缩与解压

    该文探讨了如何使用静态哈弗曼编码对文件进行压缩与解压,并提供了具体的实现代码片段。本文将详细分析其工作原理、压缩过程、解压方法以及性能评估。 #### 压缩原理与步骤 ##### 1. 构建哈弗曼树 哈弗曼树是一棵...

    哈弗曼编码的实现过程

    4. **编码数据**:使用哈弗曼编码表,将原始数据中的每个字符替换为其对应的哈弗曼编码,得到压缩后的数据。 5. **解码数据**:在接收端,通过哈弗曼树或编码表将压缩的二进制数据还原为原始字符。 在提供的源代码...

    哈弗曼编码 压缩 解压 文件

    本项目是针对数据结构实习编写的,目的是让学生理解并实现哈弗曼编码的压缩与解压过程。 首先,我们要了解哈弗曼树的构造过程。哈弗曼树是一种特殊的二叉树,也被称为最优二叉树。它的特点是所有叶子节点都是原始...

    基于哈弗曼编码实现高压缩和解压缩的C#源码

    在该C#源码项目中,"基于哈弗曼编码实现高压缩和解压缩"的核心思想是利用字符出现频率的不同,构建出一个具有最小带权路径长度的哈弗曼树,以此来实现高效的压缩和解压缩过程。 首先,我们需要理解哈弗曼树的构建...

    哈弗曼编码译码器的实现

    在这个项目中,学生需要实现哈弗曼树的建立,以及基于哈弗曼编码的文件压缩和解压缩功能。以下是关于这个主题的详细知识讲解: 1. **哈弗曼树(Huffman Tree)**:哈弗曼树是一种特殊的二叉树,也称为最优二叉树。...

    哈弗曼编码的设计和实现

    通过运行这个可执行文件,用户可以输入待压缩的文件,程序会自动生成一个哈弗曼编码压缩后的文件。解压缩时,只需再次运行程序,提供压缩后的文件,即可恢复原始数据。 哈弗曼编码在很多领域都有应用,如文本压缩、...

    哈弗曼编码实现文件压缩

    哈弗曼编码的优点在于其无损性,压缩和解压缩不会丢失任何信息。然而,对于某些文件类型,如已经经过有损压缩的音频或视频,哈弗曼编码可能无法达到很好的压缩率,因为这些文件中的数据分布可能不均匀,且存在大量...

    哈弗曼编码译码(C++实现,源码+可执行程序+实验报告)

    哈弗曼编码是一种高效的数据压缩方法,由美国学者大卫·哈弗曼在1952年提出。这种编码方式利用了字符出现频率的不同,构建出一棵特殊的二叉树——哈弗曼树,使得频率高的字符拥有较短的编码,频率低的字符编码较长,...

    哈弗曼编码与译码,哈弗曼编码与译码

    哈弗曼编码的优点在于其压缩效率高,尤其对于包含大量重复字符的数据,压缩效果显著。但它的缺点是编码和解码过程中需要构建和维护哈弗曼树,这在内存和计算资源有限的情况下可能成为限制因素。 在实际应用中,...

    哈弗曼编码实现压缩解压

    而在`HUFF`这个文件中,可能包含了用哈弗曼编码压缩的数据以及相关的编码表信息。 总结来说,哈弗曼编码是一种基于频率优化的编码技术,适用于数据压缩。在C++中实现哈弗曼编码与解压,需要理解哈弗曼树的构建过程...

    VC++中哈弗曼编码实现

    哈弗曼编码是一种高效的数据压缩方法,主要用于无损数据压缩,由哈弗曼在1952年提出。它的核心思想是构建一棵特殊的二叉树,即哈弗曼树,其中每个叶节点代表一个需要编码的字符,而内部节点则表示路径。字符出现频率...

    哈弗曼编码实现文本文件和图片的压缩

    以下是关于哈弗曼编码实现文本文件和图片压缩的详细知识讲解。 一、哈弗曼编码原理 哈弗曼编码的基本思想是构建一棵特殊的二叉树,称为哈弗曼树。这棵树满足以下两个特性: 1. 所有叶子节点代表待编码的原始数据...

    哈弗曼编码 压缩与解压缩

    在本实验中,你可能会使用VC++作为编程环境来实现哈弗曼编码的压缩和解压缩过程。VC++是一个强大的C++集成开发环境,支持各种算法和数据结构的实现。你可以编写函数来构建哈弗曼树,生成编码表,以及进行压缩和解...

    数据结构课程设计,实现哈弗曼编码解码

    在数据结构与算法的课程设计中,哈弗曼编码是一项重要的主题,它涉及到树形结构、优先队列以及编码理论。哈弗曼编码是一种广泛应用于数据压缩领域的编码技术,由David A. Huffman在1952年提出,主要用于无损数据压缩...

    哈弗曼编码 图像处理 压缩率

    在实际应用中,哈弗曼编码常与其他图像压缩技术结合使用,如DCT(离散余弦变换)或JPEG压缩,以进一步提高压缩效率。哈弗曼编码由于其效率和无损特性,被广泛应用于文本、图像和音频等数据的压缩,特别是在文件传输...

    哈弗曼编码文件2进制压缩并解压缩

    哈弗曼编码文件2进制压缩并解压缩,纯C++代码。可以将文本文档压缩成2进制编码(打开压缩文档是乱码)、还可以解压缩。压缩比例20%-50%

    基于哈弗曼编码的压缩率问题进行介绍

    本文将详细介绍基于哈弗曼编码的压缩原理、压缩率计算方法以及其实现过程,并探讨如何优化以获得更好的压缩效果。 #### 二、哈弗曼编码基础 哈弗曼编码的基本思想是为不同频率出现的字符分配不同长度的编码。更...

    哈弗曼编码(C语言)

    3. 编码压缩:使用生成的编码,我们可以对文件进行压缩,减少文件的大小。 哈弗曼编码是一种高效的数据压缩方法,通过构建哈弗曼树,可以生成最优的前缀编码。该方法广泛应用于数据压缩、图像压缩、视频压缩等领域...

Global site tag (gtag.js) - Google Analytics