package com.zhao.algorithm.tree;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* AUTHOR :zhao
* 日期:2020/2/16 17:05
* 赫夫曼数 :当用 n 个结点(都做叶子结点且都有各自的权值)试图构建一棵树时,如果构建的这棵树的带权路径长度最小,
* 称这棵树为“最优二叉树”,有时也叫“赫夫曼树”或者“哈夫曼树”。
*/
public class HuffmanTree {
public static void main(String[] args) {
int [] array={3,7,29,8,11,5,14,23};
Node wplTree = creatHuffmanTree(array);
System.out.println(wplTree);
}
/**
* 构建哈夫曼树时,需要每次根据各个结点的权重值,筛选出其中值最小的两个结点,然后构建二叉树。
* 查找权重值最小的两个结点的思想是:从树组起始位置开始,首先找到两个无父结点的结点(说明还未使用其构建成树),然后和后续无父结点的结点依次做比较,有两种情况需要考虑:
* @param arr 二叉树组
* @return wpl :树的带权路径长度为树中所有叶子结点的带权路径长度之和。通常记作 "WPL"
*/
public static Node creatHuffmanTree(int[]arr){
//1.使用数组中的元素创建只有就一个节点的二叉树
List<Node> nodeList=new ArrayList<>();
for (int v:arr){
nodeList.add(new Node(v));
}
// Collections.sort(nodeList);
// System.out.println(nodeList);
//当只剩一个节点时停止
while (nodeList.size()>1) {
//2.将所有的二叉树进行排序
Collections.sort(nodeList);
// System.out.println(nodeList);
//3.取出最小的2为二叉树构造一个新的二叉树
Node leftNode = nodeList.get(nodeList.size()-1);
Node rightNode = nodeList.get(nodeList.size()-2);
Node parent = new Node(leftNode.getValue() + rightNode.getValue());
//4.移除刚才的2个二叉树
nodeList.remove(leftNode);
nodeList.remove(rightNode);
//5.把构造的新的二叉树添加进去
nodeList.add(parent);
Integer.parseInt("", 2);
}
//6.获取wpl
return nodeList.get(0);
}
}
package com.zhao.algorithm.tree;
/**
* AUTHOR :zhao
* 日期:2020/2/16 17:00
* 节点类
* 实现接口 Comparable 就可以 使用 Collections.sort(); 对里面的集合数据进行拍序了
*/
public class Node implements Comparable<Node>{
public int getValue() {
return value;
}
private int value;
private Node leftNode;
private Node rightNode;
public Node(int value){
this.value = value;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
@Override
public int compareTo(Node o) {
/**
* 返回整数大于
* 0 等于
* 负数 小于
*/
//按倒序排
return -(this.value-o.value);
}
}