哈夫曼树
介绍:
1) 一颗二叉树,给定n个权值作为n个叶子结点,若该树带权路径长度(WPL)达到最小,就称为最优二叉树,也称哈夫曼树。
2)哈夫曼树WPL最小,权值较大的结点离根较近。
构建哈夫曼树的步骤:
1)从小到大排序,每次取出根节点权值最小和次小的两颗二叉树。
2)将两颗二叉树构成新的二叉树,新二叉树根节点权值是前面两权值的和。
3)数列中去除最小和次小的数据,添加新的二叉树的权值数据,重新排序。
4)重复1-2-3的步骤。
5)图解
代码实现:
package tree;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class HuffmanTree {
public static void main(String[] args) {
int[] arr = {13,7,8,3,29,6,1};
Node node = createHuffmanTree(arr);
// node.preOrder();
preOrder(node);
}
//
public static void preOrder(Node root){
if (root != null){
root.preOrder();
}else{
System.out.println("空树!!!");
}
}
//创建赫夫曼树
public static Node createHuffmanTree(int[] arr) {
List<Node> nodes = new ArrayList<Node>();
for (int value : arr) {
nodes.add(new Node(value));
}
while (nodes.size() > 1) {
Collections.sort(nodes);
// System.out.println("nodes =" + nodes);
//取出权值最小的两颗二叉树
//(1)取出最小和次小的值
Node leftNode = nodes.get(0);
Node rightNode = nodes.get(1);
//(2)构建一个新二叉树
Node parent = new Node(leftNode.value + rightNode.value);
parent.left = leftNode;
parent.right = rightNode;
//(3)ArrayList中删除处理过的二叉树
nodes.remove(leftNode);
nodes.remove(rightNode);
//(4)添加新的parent进nodes
nodes.add(parent);
//排序
Collections.sort(nodes);
// System.out.println(nodes);
}
return nodes.get(0);
}
}
//创建结点类
class Node implements Comparable<Node>{
int value;
Node left;
//
public void preOrder(){
System.out.println(this);
if (this.left != null){
this.left.preOrder();
}
if (this.right != null){
this.right.preOrder();
}
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
Node right;
public Node(int value) {
this.value = value;
}
public String Node(int value){
return "Node [value="+ value +"]";
}
@Override
public int compareTo(Node o) {
//表示从大到小
return this.value -o.value;
}
}