总体而言就是路径的统计那里我想了好久,还需要深刻理解递归的思想.
package HuffmanCode;
import java.util.*;
public class HuffmanCodeDemo01 {
public static void main(String[] args) {
String content = "i like like like java do you like a java";
byte[] bytes = content.getBytes(); // 把String 中的每个字符取出
List<Node> nodes = getNodes(bytes);
// System.out.println(nodes);
// System.out.println(bytes.length); //40个字节 也就320位
Node tree = createTree(nodes);
tree.pre();
}
// 接收一个字节数组,返回的就是一个List 里面有 Node["97",5]
private static List<Node> getNodes(byte[] bytes) {
// 先创建一个ArrayList
ArrayList<Node> nodes = new ArrayList<>();
HashMap<Byte, Integer> byteIntegerHashMap = new HashMap<>();
// 存储每个byte 出现的次数 -> map<key ,value>
for (byte b : bytes
) {
Integer integer = byteIntegerHashMap.get(b); // 返回的是value值
if (integer == null) {
byteIntegerHashMap.put(b, 1);
} else {
byteIntegerHashMap.put(b, integer + 1);
}
}
// 把每个键值对转成一个Node对象 然后加入到这个容器里面
for (Map.Entry<Byte, Integer> entry : byteIntegerHashMap.entrySet()) {
nodes.add(new Node(entry.getKey(), entry.getValue()));
}
return nodes;
}
// 通过一个list 创建一个赫夫曼树
private static Node createTree(List<Node> nodes){
while (nodes.size()>1){
// 排序
Collections.sort(nodes);
// 取出前面两个树
Node left = nodes.get(0);
Node right = nodes.get(1);
Node parent=new Node(left.weight+right.weight);
parent.left=left;
parent.right=right;
nodes.add(parent);
// 再连接上他们之间的关系
// 再移除两个树
nodes.remove(left);
nodes.remove(right);
}
return nodes.get(0); // 增加两个删除一个,到最后数组中只要一个root结点存在
}
static Map<Byte,String> map=new HashMap<Byte, String>();
static StringBuilder stringBuilder=new StringBuilder();
// 生成对应的赫夫曼编码表
/**
*
* @param node
* @param code 路径: 左子节点为0 右子节点为1
* @param stringBuilder
*/
private static void getCodes(Node node,String code,StringBuilder stringBuilder){
StringBuilder stringBuilder1 = new StringBuilder(stringBuilder);
stringBuilder1.append(code);
if (node!=null){ // 如果node ==null 不处理
if(node.data==null){ // 非叶子节点
getCodes(node.left,"0",stringBuilder1);
getCodes(node.right,"1",stringBuilder1);
}
else {
map.put(node.data,stringBuilder1.toString());
}
}
}
}
// Node 结点的信息
class Node implements Comparable<Node>
{
Byte data; // 存放数据本身 ,根据AcsII码值存储
int weight; // 获取权值,表示字符出现的次数
Node left;
Node right;
Node(int weight){
this.weight=weight;
}
Node(Byte data, int weight) {
this.data = data;
this.weight = weight;
}
@Override
public int compareTo(Node o) {
return this.weight - o.weight;
}
@Override
public String toString() {
return "Node{" +
"data=" + data +
", weight=" + weight +
'}';
}
// 前序遍历
public void pre() {
System.out.println(this);
if (this.left != null) {
this.left.pre();
}
if (this.right != null) {
this.right.pre();
}
}
}