1. 概念
赫夫曼树: 给定n个权值作为n个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为最优二叉树,也叫赫夫曼树(Huffman Tree)。
路径:从一个节点往下可以达到的孩子或者孙子节点之间的通路,称之为路径。
路径长度:通路中的分支数目称之为路径长度,若规定根节点的层数为1,则从根节点到第L层节点的路径长度为L-1。
权:将书中的节点赋给一个有某种意义的数值,则这个数值称之为给节点的权。
带权路径长度:从根节点到该节点之间的路径长度与该节点的权的乘积。
2. 将数列转成赫夫曼树
- 思路
1、写Node类,其中Node类需要继承Comparable类,实现其中的compareTo()方法,为的是实现Node数组的排序(java自带的排序)
2、将举例子的数组值转化为list<Node>值并排序 3、将list中最小的两个node拿出,并构成一个二叉树,将父节点的值写成左右子节点的值的和,并将父节点加入到list中去 4、重复2、3操作,直到list只有一个元素。
- 代码
package tree;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class HuffmanTree {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = {2,7,4,3,1,9,8,0};
HuffmanTree huffmanTree = new HuffmanTree();
Node node = huffmanTree.buildHuffmanTree(arr);
System.out.println(node.toString());
}
//构建哈弗曼树
public Node buildHuffmanTree(int[] arr) {
Node pareNode;
ArrayList<Node> list = new ArrayList<Node>();
//1、将arr转换为list,并排序
for (int i = 0; i < arr.length; i++) {
list.add(new Node(arr[i]));
}
// Collections.sort(list);
// System.out.println(list);
while(list.size() > 1) {
Collections.sort(list);
System.out.println(list);
//2、取出最小的两个数,进行拼接node
pareNode = new Node(list.get(0).getValue()+list.get(1).getValue());
pareNode.setLeftNode(list.get(0));
pareNode.setRightNode(list.get(1));
//3、list剔除lsftNode和rightNode,并加入parentNode
list.remove(0);
list.remove(0);
list.add(pareNode);
}
return list.get(0);
}
}
//树节点
class Node implements Comparable<Node>{
private int value;
private Node leftNode;
private Node rightNode;
public int getValue() {
return value;
}
public Node(int value) {
this.value = value;
}
public void setValue(int value) {
this.value = value;
}
public Node getLeftNode() {
return leftNode;
}
public void setLeftNode(Node leftNode) {
this.leftNode = leftNode;
}
public Node getRightNode() {
return rightNode;
}
public void setRightNode(Node rightNode) {
this.rightNode = rightNode;
}
@Override
public String toString() {
return "Node [value=" + value + "]";
}
@Override
public int compareTo(Node o) {
// TODO Auto-generated method stub
return this.value - o.getValue();//升序
}
}