一、哈夫曼树也叫赫夫曼树,是一颗权值路径最小的二叉树。
我们用的测试数据是 :{6,32,15,21,3,43,69,52,39,70};
二、构建完的树如下图:
三、代码实现
package com.cn.test.tree;
import java.util.*;
public class HalfManTree {
public static void main(String[] args) {
//构建哈夫曼树的节点
int[] data = {6,32,15,21,3,43,69,52,39,70};
System.out.println("原始的数据:"+ Arrays.toString(data));
//构建
HalfManTreeNode halfManTreeNode = HalfManTreeNode(data);
//构建完之后的root节点
System.out.println("构建完之后的root节点:"+halfManTreeNode);
System.out.print("先序打印哈夫曼树树:");
prePrint(halfManTreeNode);
//打印每一个页节点的路径值
System.out.println();
prePrintRoute(halfManTreeNode, "");
//找出某一个值的路径
System.out.println("查询一个特定值的路径。。。。。。。。。。。。。");
int key = 39;
String route = prePrintRouteByValue(halfManTreeNode, "", key);
System.out.println(key+"的路径是:"+route);
}
public static HalfManTreeNode HalfManTreeNode(int[] data){
if(data == null){
return null;
}
//1、把数组元素构建成节点
List list = new ArrayList();
for(int d:data){
list.add(new HalfManTreeNode(d));
}
System.out.println("节点list:"+list);
while (list.size()>1){
Collections.sort(list);
HalfManTreeNode leftNode = list.get(0);
HalfManTreeNode rightNode = list.get(1);
HalfManTreeNode parentNode = new HalfManTreeNode(leftNode.getValue()+rightNode.getValue());
parentNode.setLeftNode(leftNode);
parentNode.setRightNode(rightNode);
list.remove(0);
list.remove(0);
list.add(parentNode);
}
return list.get(0);
}
/**
* 前序打印树
* @param halfManTreeNode
*/
public static void prePrint(HalfManTreeNode halfManTreeNode){
if(halfManTreeNode == null){
return;
}
System.out.print(halfManTreeNode.getValue()+" ");
if(halfManTreeNode.getLeftNode()!=null){
prePrint(halfManTreeNode.getLeftNode());
}
if(halfManTreeNode.getRightNode()!=null){
prePrint(halfManTreeNode.getRightNode());
}
}
/**
* 打印每一个元素的路径
* 向左是0,右是1
* @param halfManTreeNode
*/
public static void prePrintRoute(HalfManTreeNode halfManTreeNode,String route){
if(halfManTreeNode == null){
return;
}
if(halfManTreeNode.getRightNode() == null && halfManTreeNode.getLeftNode() == null){
System.out.println(halfManTreeNode.getValue()+" 路径是 "+ route);
}
if(halfManTreeNode.getLeftNode()!=null){
prePrintRoute(halfManTreeNode.getLeftNode(),route+"0");
}
if(halfManTreeNode.getRightNode()!=null){
prePrintRoute(halfManTreeNode.getRightNode(),route+"1");
}
}
/**
* 前序打印树
* @param halfManTreeNode
*/
public static String prePrintRouteByValue(HalfManTreeNode halfManTreeNode,String route,int value){
if(halfManTreeNode == null){
return null;
}
if(halfManTreeNode.getRightNode() == null && halfManTreeNode.getLeftNode() == null && halfManTreeNode.getValue() == value){
return route;
}
if(halfManTreeNode.getRightNode() == null && halfManTreeNode.getLeftNode() == null){
return null;
}
if(halfManTreeNode.getLeftNode()!=null){
String s = prePrintRouteByValue(halfManTreeNode.getLeftNode(), route + "0", value);
if(s!=null){
return s;
}
}
if(halfManTreeNode.getRightNode()!=null){
String s = prePrintRouteByValue(halfManTreeNode.getRightNode(), route + "1", value);
if(s!=null){
return s;
}
}
return null;
}
}
class HalfManTreeNode implements Comparable{
private int value;
private HalfManTreeNode leftNode;
private HalfManTreeNode rightNode;
public HalfManTreeNode(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public HalfManTreeNode getLeftNode() {
return leftNode;
}
public void setLeftNode(HalfManTreeNode leftNode) {
this.leftNode = leftNode;
}
public HalfManTreeNode getRightNode() {
return rightNode;
}
public void setRightNode(HalfManTreeNode rightNode) {
this.rightNode = rightNode;
}
@Override
public String toString() {
return "HalfManTreeNode{" +
"value=" + value +
'}';
}
@Override
public int compareTo(HalfManTreeNode o) {
return this.value - o.value;
}
}
四、打印结果:
原始的数据:[6, 32, 15, 21, 3, 43, 69, 52, 39, 70]
节点list:[HalfManTreeNode{value=6}, HalfManTreeNode{value=32}, HalfManTreeNode{value=15}, HalfManTreeNode{value=21}, HalfManTreeNode{value=3}, HalfManTreeNode{value=43}, HalfManTreeNode{value=69}, HalfManTreeNode{value=52}, HalfManTreeNode{value=39}, HalfManTreeNode{value=70}]
构建完之后的root节点:HalfManTreeNode{value=350}
先序打印哈夫曼树树:350 141 70 71 32 39 209 88 43 45 21 24 9 3 6 15 121 52 69
70 路径是 00
32 路径是 010
39 路径是 011
43 路径是 100
21 路径是 1010
3 路径是 101100
6 路径是 101101
15 路径是 10111
52 路径是 110
69 路径是 111
查询一个特定值的路径。。。。。。。。。。。。。
39的路径是:011