- 最优二叉树(赫夫曼数)
- 定义
- 如何构建赫夫曼树
- JAVA实现
- 什么叫路径?
从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径。
一个祖先结点到子孙结点之间的分支构成这两个结点的路径。
- 什么叫路径长度?
路径上的分支数量称为路径长度。
- 什么是树的路径长度?
树的路径长度是从树根到每一结点的路径长度之和。
n n n个结点的二叉树中,完全二叉树就是最短路径长度的二叉树。
- 什么是结点的权
给每一个结点赋予一个新的数值,被称为这个结点的权。
- 结点的带权路径长度是什么?
结点的带权路径长度为从该结点到树根之间路径长度与结点上权的乘积。
树的带权路径长度为树中所有叶子结点的带权路径长度之和。 记做 W P L WPL WPL。
假设有 n n n个权值 { W 1 , W 2 , ⋅ ⋅ ⋅ , W n } \mathrm{\{W_1,W_2,···,W_n \}} {W1,W2,⋅⋅⋅,Wn},试图构造一颗有 n n n个叶子结点的二叉树,每个叶子结点带权值 W i \mathrm{W_i} Wi,其中带权路径长度 W P L WPL WPL最小的二叉树称为最优二叉树。
赫夫曼树表现不唯一。
如何构建赫夫曼树(1)根据给定的n个权值 { W 1 , W 2 , ⋅ ⋅ ⋅ , W n } \mathrm{\{W_1, W_2,···,W_n\}} {W1,W2,⋅⋅⋅,Wn}构成n棵二叉树的集合 F = { T 1 , T 2 , ⋅ ⋅ ⋅ , T n } F=\{T_1,T_2,···,T_n\} F={T1,T2,⋅⋅⋅,Tn},其中每颗二叉树 T i T_i Ti中只有一个带权 W i W_i Wi的根结点,其左右子树均空。
(2)在 F F F中选取两棵根结点的权值最小的树作为左、右子树构成一棵新的二叉树,且置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和。
(3)在 F F F中删除这两棵树,同时将新得到的二叉树加入到F中。
(4)重复(2)和(3),直到F只含有一棵树位置,此时的树即赫夫曼数。
JAVA实现构建哈夫曼树时,需要每次根据各个结点的权重值,筛选出其中值最小的两个结点,然后构建二叉树。
查找权重值最小的两个结点的思想是:从树组起始位置开始,首先找到两个无父结点的结点(说明还未使用其构建成树),然后和后续无父结点的结点依次做比较,有两种情况需要考虑:
- 如果比两个结点中较小的那个还小,就保留这个结点,删除原来较大的结点;
- 如果介于两个结点权重值之间,替换原来较大的结点;
package tree;
/**
* @author
* @date
*/
public class HuffmanTreeNode {
/**
* 值
*/
private final Integer value;
private HuffmanTreeNode left;
private HuffmanTreeNode right;
/**
* 权值
*/
private final int weight;
public HuffmanTreeNode(Integer value, int weight) {
this.value = value;
this.weight = weight;
}
@Override
public String toString() {
return "HuffmanTreeNode[value=" + this.value + ", weight=" + this.weight + "]";
}
public Integer getValue() {
return value;
}
public HuffmanTreeNode getLeft() {
return left;
}
public void setLeft(HuffmanTreeNode left) {
this.left = left;
}
public HuffmanTreeNode getRight() {
return right;
}
public void setRight(HuffmanTreeNode right) {
this.right = right;
}
public int getWeight() {
return weight;
}
}
package tree;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
/**
* @author
* @date
*/
public class HuffmanTree {
public static void main(String[] args) {
List nodes = new ArrayList();
nodes.add(new HuffmanTreeNode(1, 40));
nodes.add(new HuffmanTreeNode(2, 8));
nodes.add(new HuffmanTreeNode(3, 10));
nodes.add(new HuffmanTreeNode(4, 30));
nodes.add(new HuffmanTreeNode(5, 10));
nodes.add(new HuffmanTreeNode(6, 2));
HuffmanTreeNode root = HuffmanTree.createTree(nodes);
System.out.println(breadthFirst(root));
}
public static HuffmanTreeNode createTree(List nodes) {
// 结点数据nodes,还满足构造一个二叉树
while (nodes.size() > 1) {
sortNodes(nodes, 0, nodes.size() - 1);
HuffmanTreeNode left = nodes.get(nodes.size() - 1);
HuffmanTreeNode right = nodes.get(nodes.size() - 2);
HuffmanTreeNode parent = new HuffmanTreeNode(null, left.getWeight() + right.getWeight());
parent.setLeft(left);
parent.setRight(right);
nodes.remove(nodes.size() - 1);
nodes.remove(nodes.size() - 1);
nodes.add(parent);
}
return nodes.get(0);
}
/**
* 对结点进行排序
*
* @param nodes
*/
private static void sortNodes(List nodes, int start, int end) {
if (start start && nodes.get(--j).getWeight()
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?