概述
由相同权值的一组叶子结点所构成的二叉树可能有不同的形态和不同的带权路径长度,具有最小带权
路径长度的二叉树称为赫夫曼(Haffman)树。也称最优二叉树,它是n个带权叶子节点构成的所有二
叉树中,带权路径长度最小的二叉树。
节点的权:二叉树中的每个叶子节点经常对应一个有实际意义的数据,这个数据称为该节点的权。
带权路径长度(WPL):树中所有叶子节点的带权路径长度之和。在二叉树中,二叉树的路径长
度是指由根节点到所有叶子节点的路径长度之和。假设二叉树具有n个带权值的叶节点,那么从根节点
到各个叶子节点的路径长度与相应节点权值的乘积之和叫做二叉树的带权路径长度(weighted path
length)。
如上图所示:
(a)
WPL = 92+42+52+22 = 40
(b)
WPL = 91+52+43+23 = 37
(c)
WPL = 41+22+53+93 = 50
综上可知:二叉树的带权路径长度 WPL = 节点的权值乘以从根节点到当前节点所经过的节点数,也
可以看出,权值越大的节点离根节点越近的二叉树才是最优二叉树。
创建赫夫曼树流程分析
1、排序
2、取出根节点权值最小的两棵二叉树
3、组成新的一棵二叉树,前面取出来的两棵树是新二叉树的两棵子树
4、根节点的权值是前面取出来的两棵二叉树的根节点的权值之和
代码展示
节点类
package demo8;
public class Node implements Comparable<Node>{
int value;
int left;
int 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 demo8;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestHuffmanTree {
public static void main(String[] args) {
int[] arr = new int[]{3,7,8,29,5,11,23,14};
Node node = createHuffmanTree(arr);
System.out.println(node);
}
//创建赫夫曼树
public static Node createHuffmanTree(int[] arr){
//先使用数组中所有的元素创建若干个二叉树(开始只有一个节点)
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);
}
}