4.17 数据压缩之创建赫夫曼树

上节回顾:

数据结构与算法【基础版】:4.17 数据压缩之创建赫夫曼树_二叉树

图例:

数据结构与算法【基础版】:4.17 数据压缩之创建赫夫曼树_List_02

代码:

首先创建一个Node类

package main.java.com.LiKou.demo10;

public class Node implements Comparable<Node>{
//代表值
Byte data;
//代表权值
int weight;
Node left;
Node right;
public Node(Byte data, int weight){
this.data = data;
this.weight = weight;
}

//倒序
@Override
public int compareTo(Node o) {
return o.weight - this.weight;
}

@Override
public String toString() {
return "Node{" +
"data=" + data +
", weight=" + weight +
'}';
}
}

在创建TestHuffmanCode类

package main.java.com.LiKou.demo10;

import java.util.*;

public class TestHuffmanCode {
public static void main(String[] args) {
String msg = "can you can a can as a can canner can a can.";
byte[] bytes = msg.getBytes();
//进行赫夫曼编码
byte[] b = huffmanZip(bytes);
}

/**
* 这是对赫夫曼数的压缩
* @param bytes
* @return
*/
private static byte[] huffmanZip(byte[] bytes) {
//先统计每个byte出现的次数,并放入一个集合中
List<Node> nodes = getNodes(bytes);
//创建一棵赫夫曼树
Node tree = createHuffmanTree(nodes);
System.out.println(tree);//测试赫夫曼树的正确性
System.out.println(tree.left);//测试赫夫曼树的左子树
System.out.println(tree.right);//测试赫夫曼树的右子树
//创建一个赫夫曼编码表
//编码
return null;
}

/**
* 用来创建赫夫曼树的
* @param nodes
* @return
*/
private static Node createHuffmanTree(List<Node> nodes) {
while (nodes.size() > 1){
//排序需要再Node类上实现Comparable——这个类才能进行排序(倒序,小的在前面)
Collections.sort(nodes);
//取出两个权值最低的二叉树
Node left = nodes.get(nodes.size() - 1);
Node right = nodes.get(nodes.size() - 2);
//创建一棵新的二叉树
Node parent = new Node(null, left.weight + right.weight);
//把之前取出来的两棵二叉树设置为新创建的二叉树的子树
parent.left = left;
parent.right = right;
//把前面取出来的两棵二叉树删除
nodes.remove(left);
nodes.remove(right);
//把新创建的二叉树放入集合中
nodes.add(parent);
}
return nodes.get(0);
}

/**
* 把byte数组转为node集合
* @param bytes
* @return
*/
private static List<Node> getNodes(byte[] bytes) {
List<Node> nodes = new ArrayList<>();
//存储每一个byte出现了多少次
Map<Byte, Integer> counts = new HashMap<>();
//统计每一个byte出现的次数
for(byte b : bytes){
Integer count = counts.get(b);
if(count == null){
counts.put(b, 1);
}else {
counts.put(b, count + 1);
}
}

///把每一个键值对转为一个node对象
for(Map.Entry<Byte, Integer> entry : counts.entrySet()){
nodes.add(new Node(entry.getKey(), entry.getValue()));
}
return nodes;
}
}

结果:

数据结构与算法【基础版】:4.17 数据压缩之创建赫夫曼树_List_03