附上完整的代码

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. C++ Primer笔记4_静态成员类_IO库

    1.静态成员类 static成员变量与函数 static成员变量:必须在类外初始化.(const或引用类型变量必须在构造函数初始化列表里初始化) static成员函数: 不依赖于类.相当于类里的全局函 ...

  2. C——联合体(共同体)总结

    联合体的特点 1.联合体是一种结构,在这个结构中能够不同类型的成员,但同一时间仅仅能存放当中的一种. #include <stdio.h> union Demo { int a; char ...

  3. Https 客户端与服务器交互过程梳理(转)

    本文试图以通俗易通的方式介绍Https的工作原理,不纠结具体的术语,不考证严格的流程.我相信弄懂了原理之后,到了具体操作和实现的时候,方向就不会错,然后条条大路通罗马.阅读文本需要提前大致了解对称加密 ...

  4. DFS PKU 1562

    简单地DFS Oil Deposits Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12801   Accepted: 6 ...

  5. 【剑指offer】堆栈推弹出序列

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/26077863 剑指offer上的第22题,九度OJ上AC. 题目描写叙述: 输入两个整数序 ...

  6. MySQL当您插入列无效的数据插入

    1.错误叙述性说明 com.mysql.jdbc.exception:jdbc4.MySQLSyntaxErrorException:Unknown column 'man' in 'field li ...

  7. Eclipse UML小工具AmaterasUML的配置和使用

    AmaterasUML是个人认为最好用的Eclipse UML插件,能够通过拖拽Java源文件,轻松生成类图结构.同一时候支持活动图.时序图和用例图. 它的官方下载地址是:http://sourcef ...

  8. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(11)-验证码实现和底层修改

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(11)-验证码实现和底层修改 ASP.NET MVC+EF框架+EasyUI实现权限管系列  (开篇)   (1):框架搭建    ...

  9. android 登录推断是否邮箱或手机号

    /** * 验证邮件是合法的输入 *  * @param strEmail * @return */ public static boolean isEmail(String strEmail) { ...

  10. 自己定义GSON类型适配器

    Exception in thread "main" java.lang.RuntimeException: No-args constructor for class java. ...