赫夫曼树
Posted liuzhidao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了赫夫曼树相关的知识,希望对你有一定的参考价值。
基本介绍
- 给定n个权值作为n个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,这样的二叉树为最优二叉树,也称为赫夫曼树
- 赫夫曼树是带权路径长度最短的数,权值较大的节点离根较近
赫夫曼树几个重要概念
- 1.路径和路径长度:在一棵树中,从一个节点往下可以达到的孩子或孙子节点之间的通路,称为路径.通路中分支的数目称为路径长度.若规定根节点的层数为1,则从根节点到第L层节点的路径长度为L-1
-
- 节点的权及带权路径长度:若将树中节点赋给一个有着某种含义的数值,则这个数值称为该节点的权.节点的带权路径长度为:从根节点到该节点之间的路径长度与该节点的权的乘积.
-
- 树的带权路径长度:树的带权路径长度规定为所有叶子节点的带权路径长度之和,记为WPL,权值越大的节点离根节点越近
- WPL最小的就是赫夫曼树
赫夫曼树创建思路图解
给你一个数列{13, 7, 8, 3, 29, 6, 1},要求转成一棵赫夫曼树.
构成赫夫曼树的步骤:
- 从小到大进行排序,将每一个数据都是一个节点,每个节点可以看成是一棵简单的二叉树
- 取出根节点权值最小的两颗二叉树
- 组成一棵新的二叉树,该新的二叉树的根节点的权值是前面两颗二叉树根节点权值的和
- 再将这棵新的二叉树,以根节点的权值大小再次排序,不断重复 上述步骤,知道数列中所有数据都被处理,就得到一棵赫夫曼树
代码实现
public class HuffumanTree {
public static void main(String[] args) {
int[] arr = {13, 7, 8, 3, 29, 6, 1};
HuffumanNode root = createHuffumanTree(arr);
//进行前序遍历,检测是否构建成功
preOrder(root);
}
//前序遍历
public static void preOrder(HuffumanNode root){
if (root == null){
System.out.println("赫夫曼树为空");
}else {
root.preOrder();
}
}
//构建赫夫曼树
private static HuffumanNode createHuffumanTree(int[] arr) {
//1.遍历arr,将其放入list中,方便排序
List<HuffumanNode> nodes = new ArrayList<>();
for (int item:arr) {
nodes.add(new HuffumanNode(item));
}
//集合中只有一个元素时,就表示赫夫曼树构建成功了,这个元素就是根节点
while (nodes.size()>1){
//排序
Collections.sort(nodes);
//取出集合前两个元素,即最小的两个元素
HuffumanNode leftNode = nodes.get(0);
HuffumanNode rightNode = nodes.get(1);
//构成树
HuffumanNode parent = new HuffumanNode(leftNode.val + rightNode.val);
parent.left = leftNode;
parent.right = rightNode;
//从列表中删除取出的元素,并将paret添加到集合中
nodes.remove(leftNode);
nodes.remove(rightNode);
nodes.add(parent);
}
return nodes.get(0);
}
}
//因为需要进行排序,所以实现 Comparable 接口
class HuffumanNode implements Comparable<HuffumanNode>{
int val; //值
HuffumanNode left; //左节点
HuffumanNode right; //右节点
public HuffumanNode(int val) {
this.val = val;
}
@Override
public String toString() {
return "HuffumanNode{" +
"val=" + val +
‘}‘;
}
@Override
public int compareTo(HuffumanNode o) {
//从小到大
return this.val-o.val;
}
//前序遍历
public void preOrder(){
System.out.println(this);
if (this.left!=null){
this.left.preOrder();
}
if (this.right!=null){
this.right.preOrder();
}
}
}
以上是关于赫夫曼树的主要内容,如果未能解决你的问题,请参考以下文章