赫夫曼树
给定 n 个权值作为 n 个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree), 还有的书翻译为霍夫曼树。
赫夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
一些概念:
- 路径和路径长度:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为 1,则从根结点到第 L层结点的路径长度为 L-1。
- 结点的权及带权路径长度:若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。
- 树的带权路径长度:树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为 WPL(weighted path length) ,权值越大的结点离根结点越近的二叉树才是最优二叉树。
- WPL 最小的就是赫夫曼树。
创建赫夫曼树的思路
将一个数组创建为赫夫曼树。因为涉及到排序,就借用List实现。
首先创建树结点。为了实现自定义类的排序,让树节点实现Comparable接口,重写compareTo方法。这样做的目的是我们可以调用Collections.sort()或.sort()方法对我们的自定义类Node组成的List进行从小到大排序。(如果需要从大到小排序,compareTo方法就写成-(this.value-o.value))
class Node implements Comparable<Node>{
public int value;//节点的权值
Node left;//左子节点
Node right;//右子节点
public Node(int value){
this.value=value;
}
//前序遍历
public void preOrder(){
System.out.println(this);
if(thi