赫夫曼树概述及其创建

概述

由相同权值的一组叶子结点所构成的二叉树可能有不同的形态和不同的带权路径长度,具有最小带权

路径长度的二叉树称为赫夫曼(Haffman)树。也称最优二叉树,它是n个带权叶子节点构成的所有二

叉树中,带权路径长度最小的二叉树。

节点的权:二叉树中的每个叶子节点经常对应一个有实际意义的数据,这个数据称为该节点的权。

带权路径长度(WPL):树中所有叶子节点的带权路径长度之和。在二叉树中,二叉树的路径长

度是指由根节点到所有叶子节点的路径长度之和。假设二叉树具有n个带权值的叶节点,那么从根节点

到各个叶子节点的路径长度与相应节点权值的乘积之和叫做二叉树的带权路径长度(weighted path

length)。
在这里插入图片描述
如上图所示:
(a)
WPL = 92+42+52+22 = 40
(b)
WPL = 91+52+43+23 = 37
(c)
WPL = 41+22+53+93 = 50

综上可知:二叉树的带权路径长度 WPL = 节点的权值乘以从根节点到当前节点所经过的节点数,也
可以看出,权值越大的节点离根节点越近的二叉树才是最优二叉树。

创建赫夫曼树流程分析

1、排序

2、取出根节点权值最小的两棵二叉树

3、组成新的一棵二叉树,前面取出来的两棵树是新二叉树的两棵子树

4、根节点的权值是前面取出来的两棵二叉树的根节点的权值之和

代码展示

节点类
package demo8;

public class Node implements Comparable<Node>{
    int value;
    int left;
    int right;

    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 + '}';
    }
}
测试类
package demo8;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestHuffmanTree {
    public static void main(String[] args) {
        int[] arr = new int[]{3,7,8,29,5,11,23,14};
        Node node = createHuffmanTree(arr);
        System.out.println(node);
    }

    //创建赫夫曼树
    public static Node createHuffmanTree(int[] arr){
        //先使用数组中所有的元素创建若干个二叉树(开始只有一个节点)
        List<Node> nodes = new ArrayList<>();
        for(int value:arr){
            nodes.add(new Node(value));
        }
        //循环处理
        while(nodes.size()>1){
        //排序
        Collections.sort(nodes);
        //取出权值最小的两个二叉树
        //取出权值最小的二叉树
        Node left = nodes.get(nodes.size()-1);
        //取出权值次小的二叉树
        Node right = nodes.get(nodes.size()-2);
        //创建一棵新的二叉树
        Node parent = new Node(left.value+right.value);
        //把取出来的两棵二叉树移除
        nodes.remove(left);
        nodes.remove(right);
        //放入原来的二叉树集合中
        nodes.add(parent);
        }
        return nodes.get(0);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值