一、哈夫曼树概述
哈夫曼树也叫最优二叉树,它是n个带权叶子节点构成的所有二叉树中,带权路径长度最小的二叉树。
叶节点的带权路径:从根节点出发,经过的节点的数量乘以叶子节点的权值。
树的带权路径长度WPL:树中所有叶子节点的带权路径长度之和。
WPL:
权值越大的节点离根节点越近的二叉树才是最优二叉树。
二、创建哈夫曼树流程
排序
取出根节点权值最小的两棵二叉树
组成一颗新的二叉树,前面取出来的两棵二叉树是新二叉树的两个子树
根节点的权值是前面取出来的两棵二叉树的根节点的权值之和
再重新排序…递归
三、代码创建哈夫曼树
package com.demo4;
public class Node implements Comparable<Node> {
int value;
Node left;
Node right;
public Node(int value) {
this.value = value;
}
@Override
public int compareTo(Node o) {
return -(this.value - o.value);
}
@Override
public String toString() {
return "Node [value=" + value + "]";
}
}
package com.demo4;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class TestHuffmanTree {
public static void main(String[] args) {
int[] arr = { 3, 7, 8, 29, 5, 11, 23, 14 };
Node node = createHuffmanTree(arr);
System.out.println(node);
}
// 创建哈夫曼树
public static Node createHuffmanTree(int[] arr) {
// 使用数组中所有的元素创建若干个二叉树(只有1个节点)
List<Node> nodes = new ArrayList<>();
for (int value : arr) {
nodes.add(new Node(value));
}
// 循环处理
while (nodes.size() > 1) {
// 排序
Collections.sort(nodes);
// 取出来权值最小的两个二叉树(从大到小排序取最后一个)
Node left = nodes.get(nodes.size() - 1);
// 取出来权值最小的两个二叉树(从大到小排序取最后一个)
Node right = nodes.get(nodes.size() - 2);
// 创建一个新二叉树
Node parent = new Node(left.value + right.value);
// 把取出来的两个二叉树移除
nodes.remove(left);
nodes.remove(right);
// 放入原来的二叉树集合中
nodes.add(parent);
}
return nodes.get(0);
}
}
四、哈夫曼编码
定长编码
非定长编码
解码时: