附上完整的代码

http://download.csdn.net/download/u010485034/7847447

Huffman编码原理这里就不说了,是。这里来讲讲利用Huffman编码来进行压缩和解压缩的详细实现吧。

本project使用java实现。

编码

1. 流程图

2. 数据结构

CharacterWeight:记录字符值,以及其在待压缩文件里的权重。

Class{
char c; //字符值
int weight; //在文件里权重
String code; //其相应huffman编码
}

HuffmanNode:huffman树中的节点信息。

Class{
Int parent; //父节点
Int lChild; //左儿子
Int rChild; //右儿子
Int weight; //权重
}

3. 程序关键点

3.1 Huffman树的构建

Huffman树的变量:ArrayList<HuffmanNode> list。

创建流程图:

for(int i=0;i<list.size()-1;i++){
//w1 : the first min weight w2: the second min weight
//i1 : the first min weight index, i2: the second min weight index
int w1 = MAX_VALUE, w2=MAX_VALUE;
int i1 = 0, i2 = 0;
// find the two node with the minimum weight
for(int j=0;j<tree.size();j++){
HuffmanNode node = tree.get(j);
if(node.getWeight()< w1 && node.getParent()==-1){
w2 = w1;
w1 = node.getWeight();
i2 = i1;
i1 = j;
}
else if(node.getWeight()<w2 && node.getParent()==-1){
w2 = node.getWeight();
i2 = j;
}
}
//set the two node to be the children of a new node, and add the new node to the tree
HuffmanNode pNode = new HuffmanNode(w1+w2);
pNode.setlChild(i1);
pNode.setrChild(i2);
tree.add(pNode);
tree.get(i1).setParent(tree.indexOf(pNode));
tree.get(i2).setParent(tree.indexOf(pNode));}

3.2   依据Huffman 树获得Huffman编码

从叶子节点開始网上遍历Huffman树。直到到达根节点。依据当前节点为其父节点的左儿子还是右儿子确定这一位值是0还是1。

最后将依次获得的0,1字符串反转获得Huffman编码。

代码:

for(int i=0;i<list.size();i++){
HuffmanNode node = tree.get(i);
HuffmanNode pNode = tree.get(node.getParent());
String code ="";
while(true){
if(pNode.getlChild()==tree.indexOf(node)){
code = "0"+code;
}
else if(pNode.getrChild() == tree.indexOf(node)){
code = "1"+code;
}
else {
System.out.println("Tree Node Error!!!");
return null;
}
node=pNode;
if(node.getParent()!=-1)
pNode=tree.get(node.getParent());
else
break;
}
list.get(i).setCode(new String(code));
}

3.3  文件头设计

字符总数

Int 四个字节

字符种类数

Short 两个字节

叶子节点

char字符  short 父节点 3个字节

非叶子节点

Short 左儿子 short 右儿子 short父节点 6字节

文件头长度(单位: byte)

l= 9n

当中n 为字符种类数。

3.4文件内容的编码和写入

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDQ4NTAzNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

	while((temp=reader.read())!=-1){ //!= EOF
// get the code from the code table
String code = codeTable.get((char)temp);
c++;
if(c>=count/96){
System.out.print("=");
c=0;
}
try{
StringBuilder codeString = new StringBuilder(code);
outputStringBuffer.append(codeString);
while(outputStringBuffer.length()>8){
out.write(Short.parseShort(outputStringBuffer.substring(0, 8),2));
outputStringBuffer.delete(0, 8);
}
} catch(Exception e){
e.printStackTrace();
} }

解码

1. 流程图

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDQ4NTAzNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

2.   数据结构

HuffmanNode:huffman树中的节点信息。

Class{

Int parent;  //父节点

Int lChild; //左儿子

Int rChild;  //右儿子

Int weight; //权重

Char c; //相应的字符值

3.    程序关键点

3.1   重建Huffman树。在文件头中存放的原本就是Huffman树的节点信息,所以重建Huffman树是比較简单的。

代码:

	in = new DataInputStream(new FileInputStream(file));
count = in.readInt();
charNum = in.readShort();
nodeNum = 2*charNum -1;
//rebuild the huffman tree
for(int i=0;i<charNum;i++){
HuffmanNode node = new HuffmanNode((char)in.readByte());
int parent = in.readShort();
node.setParent(parent);
tree.add(node);
} for(int i=charNum;i<nodeNum;i++){
HuffmanNode node = new HuffmanNode(' ');
int l = in.readShort();
int r = in.readShort();
int p = in.readShort();
node.setlChild(l);
node.setrChild(r);
node.setParent(p);
tree.add(node);
}

3.2 解码

解码流程图

	while(true){
while(buff.length()<32){
temp = in.readInt();
String codeString = Integer.toBinaryString(temp);
while(codeString.length()<32){
codeString='0'+codeString;
}
buff.append(codeString);
}
node = tree.get(tree.size()-1);
dep = 0;
while(!(node.getlChild()==-1&&node.getrChild()==-1)){
if(dep>=buff.length()){
System.out.println( "Buff overflow");
}
if(buff.charAt(dep)=='0'){
node = tree.get(node.getlChild());
}
else if(buff.charAt(dep)=='1'){
node = tree.get(node.getrChild());
}
else{
System.out.println("Coding error");
}
dep++;
} char c = node.getCH();
num++;
if(num>=n/99){
System.out.print("=");
num=0;
}
count++;
if(count>=n){
break;
}
charBuff+=c;
if(charBuff.length()>256){
writer.write(charBuff);
charBuff="";
}
buff.delete(0, dep); } } catch(EOFException e){
//just do nothing
}
catch(Exception e){
e.printStackTrace();
} finally{
//there may be data released in the buff and charbuff, so we need to process them
while(buff.length()>0){
node = tree.get(tree.size()-1);
dep = 0;
while(!(node.getlChild()==-1&&node.getrChild()==-1)){
if(dep>=buff.length()){
break;
}
if(buff.charAt(dep)=='0'){
node = tree.get(node.getlChild());
}
else if(buff.charAt(dep)=='1'){
node = tree.get(node.getrChild());
}
else{
System.out.println("Coding error");
//return;
}
dep++;
}
char c = node.getCH();
num++;
if(num>=n/99){
System.out.print("=");
num=0;
}
count++;
if(count>=n){
break;
}
charBuff+=c;
if(charBuff.length()>256){
try {
writer.write(charBuff);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
charBuff="";
}
buff.delete(0, dep);
} try {
writer.write(charBuff);
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try{
writer.close();
} catch(IOException e){
throw e;
}

完成project没有公布,稍后更新。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

Huffman 压缩和解压缩java实现的更多相关文章

  1. [Java 基础] 使用java.util.zip包压缩和解压缩文件

    reference :  http://www.open-open.com/lib/view/open1381641653833.html Java API中的import java.util.zip ...

  2. Java 的zip压缩和解压缩

    Java 的zip压缩和解压缩 好久没有来这写东西了,今天中秋节,有个东西想拿出来分享,一来是工作中遇到的问题,一来是和csdn问候一下,下面就分享一个Java中的zip压缩技术,代码实现比较简单,代 ...

  3. Java用ZIP格式压缩和解压缩文件

    转载:java jdk实例宝典 感觉讲的非常好就转载在这保存! java.util.zip包实现了Zip格式相关的类库,使用格式zip格式压缩和解压缩文件的时候,须要导入该包. 使用zipoutput ...

  4. java工具类——java将一串数据按照gzip方式压缩和解压缩

    我要整理在工作中用到的工具类分享出来,也方便自己以后查阅使用,这些工具类都是我自己实际工作中使用的 import java.io.ByteArrayInputStream; import java.i ...

  5. java采用zip方式实现String的压缩和解压缩CompressStringUtil类

    CompressStringUtil类:不多说,直接贴代码: /** * 压缩 * * @param paramString * @return */ public static final byte ...

  6. Java对zip格式压缩和解压缩

    Java对zip格式压缩和解压缩 通过使用java的相关类可以实现对文件或文件夹的压缩,以及对压缩文件的解压. 1.1 ZIP和GZIP的区别 gzip是一种文件压缩工具(或该压缩工具产生的压缩文件格 ...

  7. Java基础--压缩和解压缩gz包

    gz是Linux和OSX中常见的压缩文件格式,下面是用java压缩和解压缩gz包的例子 public class GZIPcompress { public static void FileCompr ...

  8. Java ZIP压缩和解压缩文件(解决中文文件名乱码问题)

    Java ZIP压缩和解压缩文件(解决中文文件名乱码问题) 学习了:http://www.tuicool.com/articles/V7BBvy 引用原文: JDK中自带的ZipOutputStrea ...

  9. Java压缩和解压缩文件工具

    Java压缩和解压缩文件工具 学习了: https://www.oschina.net/code/snippet_1021818_48130 http://blog.csdn.net/gaowen_h ...

随机推荐

  1. Entity Framework笔记(二)

    前几日学习了在VS2010Console项目中使用Entity Framework,并且使用Code First模式.通过编写Model类,来生成数据库对应的表.并且,往表中写入数据以及获取表中的所有 ...

  2. JAVA多线程两个实用的辅助类(CountDownLatch和AtomicBoolean)

    AtomicBoolean它允许一个线程等待一个线程完成任务,然后运行: A boolean value that may be updated atomically. See the java.ut ...

  3. .NET单元测试艺术(3) - 使用桩对象接触依赖

    List 3.1 抽取一个设计文件系统的类,并调用它 [Test] public bool IsValidLogFileName(string fileName) { FileExtensionMan ...

  4. 新的学生说说我是如何靠APP发展赢得了亿万

    郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠.支持郝萌主,捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 14年踏入 ...

  5. SQLServer 2012异常问题(一)--故障转移群集+镜像环境导致作业执行失败

    原文:SQLServer 2012异常问题(一)--故障转移群集+镜像环境导致作业执行失败 先感谢一下我的同事们最先发现此问题,鸣谢:向飞.志刚.海云 最近在生产环境发现一个诡异的问题: 环境:WIN ...

  6. Log4j 2.0在具体解释发展先进的使用—SocketAppender远程输出(五岁以下儿童)

    Log4j2的Appenders充分考虑输出日志事件.包装和过滤可以被转发,它包含的主要输出到本地文件.输出到远程主机, 文件包.注射.而且,根据该日志文件的时间点.自己主动文件大小的储存条件. 例如 ...

  7. .net安装包自动安装Mysql数据库

    原文:.net安装包自动安装Mysql数据库 在制作.Net安装包的时候,如果项目有用到数据库,怎么能够把数据库打包安装呢?网上已经有很多自动安装Sql Server数据库的例子,但是自动安装mysq ...

  8. Matlab.NET混合编程调用Figure窗体

    原文:[原创]Matlab.NET混合编程调用Figure窗体 1.前言 做Matlab.NET混合编程好几年了,虽然Matlab很多函数忘记得差不多了,但基本的东西还是能熟练使用.特别是在C#调用M ...

  9. thinkphp学习笔记1—目录结构和命名规则

    原文:thinkphp学习笔记1-目录结构和命名规则 最近开始学习thinkphp,在下不才,很多的问题看不明白所以想拿出来,恕我大胆发在首页上,希望看到的人能为我答疑解惑,这样大家有个互动,学起来快 ...

  10. Serverlet具体解释

    Serverlet简单介绍: Servlet(Server Applet),全称Java Servlet,未有中文译文.是用Java编写的server端程序.其主要功能在于交互式地浏览和改动数据,生成 ...