一.简介
1.什么是哈夫曼树
给定N个权值作为N个叶子节点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
2.队列如何构建哈夫曼树
然后 以此类推
二.代码
1.新建Node类
public class Node implements Comparable<Node>{
/**
* 节点的权
*/
public int value;
/**
* 左节点
*/
public Node leftNode;
/**
* 右节点
*/
public Node rightNode;
public Node(int value) {
this.value = value;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
@Override
public int compareTo(Node node) {
return this.value-node.value;
}
/**
* 前序遍历
*/
public void preQuery(){
if (this != null){
System.out.println(this);
}
if (this.leftNode != null){
this.leftNode.preQuery();
}
if (this.rightNode != null){
this.rightNode.preQuery();
}
}
}
2.新建HuffManTree类
public class HuffManTree {
public static void main(String[] args) {
int array [] = {13,7,8,29,6,1};
Node node = treeToHuffManTree(array);
node.preQuery();
}
/**
* 将数列转换为哈夫曼树
*/
public static Node treeToHuffManTree(int [] huffManArray){
//创建容器,存放节点
List<Node> huffManList = new ArrayList();
//根据数列中的权值,创建对应的节点
for (int huffMan : huffManArray){
huffManList.add(new Node(huffMan));
}
while (true){
if (huffManList.size() == 1){
break;
}
//排序
Collections.sort(huffManList);
//取出最小的两个节点
Node leftNode = huffManList.get(0);
Node rightNode = huffManList.get(1);
//创建两个节点的根节点
Node rootNode = new Node(leftNode.value+rightNode.value);
rootNode.leftNode = leftNode;
rootNode.rightNode = rightNode;
//从集合中删除取出来的元素
huffManList.remove(leftNode);
huffManList.remove(rightNode);
//添加新的元素
huffManList.add(rootNode);
}
return huffManList.get(0);
}
}
三.哈夫曼编码
1.哈夫曼编码--压缩
比如有一串字符串:"ljdfljneidofal kjd fa",现在要将该字符串使用哈夫曼编码进行压缩;此时我们要将该字符串的每一个字符出现的次数进行统计;然后将该字符和该字符出现的次数(次数作为哈夫曼叶子节点的权)构成一颗哈夫曼树;然后把每一个叶子节点的哈夫曼编码取出来;此时字符串的每一个字符都有一个编码对应,如同ASCII码一样(空格的ASCII码是32)原字符串的每一个字符都对应有一个编码,该编码就是哈夫曼编码;根据这个编码把原数组的字符替换为对应的哈夫曼编码,然后将该编码每8位转换位一个btye类型的进行存储。
2.哈夫曼编码--解压
将要解压的byte类型的数组,转换为二进制(注意补位);然后把所有的二进制数据拼接到一起称为一个哈夫曼字符串;然后根据哈夫曼编码(一个哈夫曼编码对应一个byte值),从字符串的第一个字符开始比较(开始取出第一个字符和哈夫曼编码比较,如果没有,取出前两个比较,取出前三个比较...),然后字符串中的字符和哈夫曼编码中有一样的,取出该字符串哈夫曼编码对应的数据然后,把这个数据和该数据对应的哈夫曼编码存储在Map中;直到比较完,然后把map中的数据处理之后输出来如果和压缩前的数据一样,即解压完成