赫夫曼树图解与代码实现
- 构建赫夫曼树
package com.gykalc.tree;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 哈夫曼树:
* 树的带权路径最小的二叉树,也就是最优二叉树,也称为哈夫曼树
* wpl(weighted path length):(每个节点的权值 * 路径长度)的和,wpl最小时称为哈夫曼树
*/
public class HuffmanTree {
public static void main(String[] args) {
int[] array = new int[] {13, 7, 8, 3, 29, 6, 1};
Node huffmanTree = buildHuffmanTree(array);
preNode(huffmanTree);
}
public static void preNode(Node root) {
if (root == null) {
System.out.println("该哈夫曼树为空,不能遍历");
}
root.preNode();
}
public static Node buildHuffmanTree(int[] array) {
List<Node> listNode = new ArrayList<>();
for (int i = 0; i < array.length; i++) {
listNode.add(new Node(array[i]));
}
while(listNode.size() > 1) {
// 给listNode排好序了,listNode中的元素要实现comparable接口
Collections.sort(listNode);
// 从listNode中获取最小的两个元素
Node leftNode = listNode.get(0);
Node rightNode = listNode.get(1);
// 创建一个父节点,父节点权值是上面两个节点权值之和
Node parentNode = new Node(leftNode.getValue() + rightNode.getValue());
parentNode.setLeftNode(leftNode);
parentNode.setRightNode(rightNode);
// 从列表中移除上面获取的连个节点
listNode.remove(leftNode);
listNode.remove(rightNode);
// 将创建的父节点加入到集合中
listNode.add(parentNode);
}
return listNode.get(0);
}
}
class Node implements Comparable<Node> {
// 节点的权值
private int value;
// 左子节点
private Node leftNode;
// 右子节点
private Node rightNode;
/**
* 前序遍历
*/
public void preNode() {
System.out.println(this.value);
if (this.leftNode != null) {
this.leftNode.preNode();
}
if (this.rightNode != null) {
this.rightNode.preNode();
}
}
public int getValue() {
return 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;
}
public Node(int value) {
this.value = value;
}
@Override
public int compareTo(Node o) {
return this.value - o.value;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
}