哈夫曼树
给定 n 个权值,作为 n 个叶子结点,构造一个二叉树,如果该树的带权路径长度最小,就称该二叉树为最优二叉树,也称为哈夫曼树。
构建步骤
- 将权值序列从小到大排序,每个权值都看作是一个简单的二叉树。
- 取出根节点权值最小的两棵二叉树,组成一棵新的二叉树,新二叉树的根节点的值为它左右子节点的值之和。注意:对某个节点,构建过程中,使其右子节点权值不小于左子节点权值
- 以现有的二叉树的根节点的值,重新排序,重新执行步骤2。直到初始权值序列中每一个节点都加入到二叉树中,这样就构成一棵哈夫曼树。
代码如下
- 定义节点类
public class Node implements Comparable<Node> {
private int value;
private Node leftNode;
private Node rightNode;
public Node(int value) {
this.value = value;
}
//getter setter toString
//前序遍历
public void preOrder(){
System.out.println(this);
if (this.getLeftNode() != null){
this.getLeftNode().preOrder();
}
if (this.getRightNode() != null){
this.getRightNode().preOrder();
}
}
@Override
public int compareTo(Node o) {
//从小到大
return this.value-o.value;
}
}
- 构建哈夫曼树
public class HuffmanTree {
public static void main(String[] args) {
int[] array = {1,7,8,3,9,6,5};
Node root = createHuffmanTree(array);
preOrder(root);
}
public static void preOrder(Node node){
if(node == null){
return;
}
else {
node.preOrder();
}
}
public static Node createHuffmanTree(int[] array){
ArrayList<Node> nodes = new ArrayList<>();
for (int i = 0; i < array.length; i++) {
nodes.add(new Node(array[i]));
}
while (nodes.size()>1){
Collections.sort(nodes);
System.out.println(nodes);
Node node1 = nodes.get(0);//排完序第一个元素最小
Node node2 = nodes.get(1);
Node newNode = new Node(node1.getValue() + node2.getValue());
newNode.setLeftNode(node1);//左子节点的值小于右子节点
newNode.setRightNode(node2);
nodes.remove(node1);
nodes.remove(node2);
nodes.add(newNode);
}
return nodes.get(0);
}
}