几个名词
![image-20220215163349169](https://gitee.com/pakeing/typora-img/raw/master/img/image-20220215163349169.png)
路径长度:在一条路径中,每经过一个结点,路径长度都要加一。例如在一棵树中,规定根结点所在层数为1层,那么从根结点到第i层的路径长度为i-1。图中从根结点到节点c的路径长度为3.
结点的权:给每一个结点赋予一个新的数值,被称为这个结点的权。例如,图中结点a的权为7,b的权为5.
结点的带权路径长度:指的是从根结点到该结点之间的路径长度与该结点的权的乘积。例如在图中,结点b的带权路径长度为2*5=10;
==树的带权路径长度:==树中所有叶子结点的带权路径长度之和。通常记为“WPL”。例如图1中所示的这颗树的带权路径长度为:WPL = 7 * 1 + 5 * 2 + 2 * 3 + 4 * 3
WPL最短的就是哈弗曼树。
构建哈夫曼树
package com.xxxx.huffmantree;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class HuffmanTree {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr= {13,7,8,3,29,6,1};
Node root =createHuffmanTree(arr);
preOrder(root);
}
//创建哈夫曼树
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);
// System.out.println("nodes="+nodes);
//取出来权值最小的两个二叉树
Node left=nodes.get(0);
Node right=nodes.get(1);
//创建一颗新的二叉树
Node parent=new Node(left.value+right.value);
parent.left=left;
parent.right=right;
//把取出来的两个二叉树移除
nodes.remove(left);
nodes.remove(right);
//放入原来的二叉树中
nodes.add(parent);
}
return nodes.get(0);
}
public static void preOrder(Node root) {
if(root!=null) {
root.preOrder();
}else {
System.out.println("是空树,不能遍历");
}
}
}
//创建结点类
class Node implements Comparable<Node>{
int value;//结点权值
Node left;//指向左子结点
Node right;//指向右子结点
// 写一个前序遍历
public void preOrder() {
System.out.println(this);
if(this.left!=null) {
this.left.preOrder();
}
if(this.right!=null) {
this.right.preOrder();
}
}
public Node(int value) {
this.value = value;
}
@Override
public String toString() {
return "Node [value=" + value + "]";
}
@Override
public int compareTo(Node o) {
// TODO Auto-generated method stub
return this.value-o.value;
}
}