1. 介绍
1.1 哈夫曼树
- 哈夫曼树-最优二叉树:树的带权路径长度最小的二叉树;
- 权值均为叶子结点;
- 权值越大,结点距离根节点越近;

1.2 路径、路径长度、结点的权、结点的带权路径长度

1.3 树的带权路径长度WPL

2. 哈夫曼树构建步骤
- 对权值序列进行升序排列,选出其中最小的两个权值进行合并;
- 将合并结点加入权值序列,重新进行排序;
- 重复执行上述两个操作,直到序列中只剩一个节点即可完成创建;

- 上述案例的手动构建结果:

3. 代码实现
package com.northsmile.tree.huffman;
import java.util.*;
public class HuffmanTree {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int n=Integer.parseInt(scanner.nextLine());
List<TreeNode> nodes=new LinkedList<>();
for (int i=0;i<n;i++){
nodes.add(new TreeNode(Integer.parseInt(scanner.nextLine())));
}
root=createHuffmanTree(nodes);
System.out.println(calWPL());
}
private static TreeNode root;
public static TreeNode createHuffmanTree(List<TreeNode> nodes){
while (nodes.size()!=1){
nodes.sort(new Comparator<TreeNode>() {
@Override
public int compare(TreeNode o1, TreeNode o2) {
return o1.val-o2.val;
}
});
TreeNode left=nodes.get(0);
TreeNode right=nodes.get(1);
TreeNode curRoot = new TreeNode(left.val+right.val);
curRoot.left=left;
curRoot.right=right;
nodes.add(curRoot);
nodes.remove(0);
nodes.remove(0);
}
return nodes.get(0);
}
public static int calWPL(){
int wpl=0;
Deque<TreeNode> queue=new ArrayDeque<>();
queue.offer(root);
int height=0;
while (!queue.isEmpty()){
int size=queue.size();
for (int i=0;i<size;i++){
TreeNode cur = queue.pop();
if (cur.left==null&&cur.right==null){
wpl+=(cur.val*height);
}
if (cur.left!=null){
queue.offer(cur.left);
}
if (cur.right!=null){
queue.offer(cur.right);
}
}
height++;
}
return wpl;
}
private static class TreeNode{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val){
this.val=val;
}
}
}