哈夫曼编码是一种以哈夫曼树(最优二叉树,带权路径长度最小的二叉树)为基础的基于统计学的变长编码方式。其基本思想是:将使用次数多的代码转换成长度较短的编码,而使用次数少的采用较长的编码,并且保持编码的唯一可解性。在计算机信息处理中,经常应用于数据压缩。是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩。
而对于Huffman编码树的构造,我们可以采用贪心算法的思想,即循环地选择具有最低频数的两个结点,生成一棵子树,直至形成树 。
主要包括HuffmenTreeNode类、HuffmanTree类以及FileWork类,分别定义了哈夫曼编码树的节点、树的合并排序及编码还有对文件的IO操作。
1、Class HuffmanTreeNode
首先设置编码树的节点:
节点类的构造方法如下:
其中当读入文本时,对每个新读入的字符,构造一个新的Node类,出现频率num置为1;对于已经在缓冲区中出现的字符,则将这个字符与已经出现的字符,直接改变其频率即可。
2、Class FileWork
LinkedList#Encoding.readFile():读取文本文件,并将文本存放在LinkedList中返回。
void#Encoding.writeFile():将编码完成的文件写入文本。
void#Decoding.writeFile():根据编码方式,将编码文本转换回文本文件。
3、Class HuffmanTree
viod#initialize(LinkedList)、void#reset():将重复的节点合并、排序及编码
void#encoding_0(HuffmanTreeNode):将编码树的编码下一位置为0
void#encoding_1(HuffmanTreeNode):将编码树的编码下一位置为1
4、完整源码
package Experiment3;
import java.util.ArrayList;
public class HuffmanTreeNode {
private Character val; //节点中存储的待编码字符
private Integer num; //获取文本中该字符出现的频率
private ArrayList<Integer> code; //ArrayList<Integer>定义编码
public HuffmanTreeNode left; //左孩子
public HuffmanTreeNode right; //右孩子
public HuffmanTreeNode(Character val,Integer num){
this.val=val;
this.num=num;
this.code=new ArrayList<>();
}
public HuffmanTreeNode(HuffmanTreeNode left,HuffmanTreeNode right){
val=null;
num=left.num+right.num;
this.left=left;
this.right=right;
this.code=new ArrayList<>();
}
public void setCode(Integer ch) {
//以向每个节点code后置数字的形式进行编码
this.code.add(ch);
if(this.left!=null)
setCode(this.left,ch);
if(this.right!=null)
setCode(this.right,ch);
}
private void setCode(HuffmanTreeNode node,Integer ch){
//为该节点及其孩子节点编码
node.getCode().add(ch);
if(node.left!=null)
setCode(node.left,ch);
if(node.right!=null)
setCode(node.right,ch);
}
public void setNum(Integer num){
this.num+=num;
}
public Integer getNum(){
return num;
}
public Character getVal() {
return val;
}
public ArrayList<Integer> getCode(){
return code;
}
}
package Experiment3;
import java.util.Iterator;
import java.util.LinkedList;
public class HuffmanTree {
private LinkedList<HuffmanTreeNode