霍夫曼树:给定n个权值做为n个叶子节点,若该树的带权路径长度达到最小,这棵树为最优二叉树,也称赫夫曼树。
霍夫曼树中的几个概念
路径和路径长度
一棵树中,一个节点往下可以达到的孩子或孙子节点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根节点的层数为1,则从根节点到第L层节点的路径长度为L-1.
节点的权及带权路径长度
若将树中节点赋给一个有某种含义的数值,则称这个数值为该节点的全,节点的带权路径长度为:从根节点到该节点之间的路径长度与该节点的权的乘积。
树的带权路径长度
所有叶子节点的带权路径长度之和,记为WPL。 权值越大的节点距离根节点月季的二叉树草率最有二叉树 wpl最小的就是赫夫曼树
霍夫曼树代码实现
public class Node implements Comparable<Node>{
private int value;
private Node left;
private Node right;
public Node() {
}
public Node(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
@Override
public String toString() {
return "" + value;
}
@Override
public int compareTo(Node o) {
return this.value - o.value;
}
public void preorderTraversal(){
System.out.println(this);
if (this.left != null){
this.left.preorderTraversal();
}
if (this.right != null){
this.right.preorderTraversal();
}
}
}
数组转霍夫曼树工具类
public class HuffmanUtil {
public static Node createHuffmanTree(int[] array){
List<Node> nodeList = new ArrayList<>();
for (int val : array){
nodeList.add(new Node(val));
}
Node root = null;
while (nodeList.size() > 1){
//排序
Collections.sort(nodeList);
//取出前两位
Node left = nodeList.get(0);
Node right = nodeList.get(1);
//得出和,新建节点
root = new Node(left.getValue() + right.getValue());
root.setLeft(left);
root.setRight(right);
//删除旧节点,加入新节点
nodeList.remove(left);
nodeList.remove(right);
nodeList.add(root);
}
return root;
}
}
测试方法(前序遍历输出赫夫曼树)
public class TestApp {
public static void main(String[] args) {
int[] array = {13,7,8,29,6,1};
Node root = HuffmanUtil.createHuffmanTree(array);
root.preorderTraversal();
}
}