构造哈夫曼树的算法_哈夫曼树的应用数据结构

构造哈夫曼树的算法_哈夫曼树的应用数据结构一、什么是赫夫曼树给定n个权值作为n个叶子节点,构造一课二叉树,若该树的带权路径长度和(wpl)达到最小,称这样的二叉树为最优二叉树,也就是赫夫曼树。要理解这句话,我们需要了解几个关键词:路径:

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、什么是赫夫曼树

给定n个权值作为n个叶子节点,构造一课二叉树,若该树的带权路径长度和(wpl)达到最小,称这样的二叉树为最优二叉树,也就是赫夫曼树

要理解这句话,我们需要了解几个关键词:

  • 路径:从一个节点往下一个节点之间的通路。若根节点层数为1,则根节点通往L层的节点路径长度为L-1
  • 带权路径:权可以理解为节点值,而从根节点到某节点之间的路径长度与该点的权的成绩称为带权路径长度

举个例子:

image-20200717165237484

如上图所示,节点13到根节点的路径长度是2,而权是13,所以带权路径长度就是2*13=26,同理,节点7的带权路径长度是14,8是16,3是6,最终该树的带权路径长度之和(wpl)就是26+14+16+6=62。

image-20200717165733984

而该树与上图有相同的叶子节点,但是wpl却是13+16+21+9=59,这是拥有这几个相同叶子节点的树里面wpl最小的,所以这颗树就是一颗赫夫曼树。

我们不难看出,赫夫曼树最大的特点:权越大的节点越靠近根节点

二、如何构建赫夫曼树

举个例子,我们要将{6,1,3,7,13,8,29}这一串数列组建为赫夫曼树

  1. 首先,我们对齐从小到大排序,得到{1,3,6,7,8,13,29}

  2. 取出1和3,并以两节点之和4为根节点组建树

    image-20200717172110379

  3. 取出6,并与4之和10为根节点构建树

    image-20200717172201798

  4. 取出7,并与10之和17为根节点构建树

    image-20200717172314477

  5. 重复以上步骤最终得到赫夫曼树

image-20200717172440901

三、代码实现

首先先写一个节点类:

/**
 * @Author:CreateSequence
 * @Date:2020-07-17 17:31
 * @Description:赫夫曼树使用的节点
 */
public class Node implements Comparable<Node> {

    int val;
    Node left;
    Node right;

    public Node(int val) {
        this.val = val;
    }

    /**
     * 父节点的构造方法
     * @param left
     * @param right
     */
    public Node(Node left, Node right) {
        this.left = left;
        this.right = right;
        this.val = left.val + right.val;
    }

    @Override
    public String toString() {
        return "val=" + val;
    }

    /**
     * 实现排序接口,从大到小
     * @param o
     * @return
     */
    @Override
    public int compareTo(Node o) {
        return -(this.val - o.val);
    }
}

实现一个构造赫夫曼树的方法:

/**
 * @Author:CreateSequence
 * @Date:2020-07-17 17:37
 * @Description:赫夫曼树
 */
public class HuffmanTree {
    /**
     * 创建赫夫曼树
     * @param arr
     */
    public static List<Node> createHuffmanTree(int[] arr){
        //将数组元素拆分成节点
        List<Node> nodes = new ArrayList<>();
        for (int i : arr) {
            nodes.add(new Node(i));
        }

        //构建树
        while (nodes.size() > 1) {
            //排序
            Collections.sort(nodes);

            //取出最小的两个数构建树
            Node left = nodes.get(nodes.size() - 1);
            Node right = nodes.get(nodes.size() - 2);
            Node parant = new Node(left, right);

            //删除两个节点
            nodes.remove(left);
            nodes.remove(right);

            //将根节点添加至集合
            nodes.add(parant);
        }

        return nodes;
    }
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/170804.html原文链接:https://javaforall.net

(0)
上一篇 2022年8月16日 下午9:46
下一篇 2022年8月16日 下午9:46


相关推荐

  • 扣子coze老黄历教程

    扣子coze老黄历教程

    2026年3月12日
    4
  • 错位排列递推公式推导

    错位排列递推公式推导全错位排列 即被著名数学家欧拉 LeonhardEule 1707 1783 称为组合数论的一个妙题的 装错信封问题 装错信封问题 是由当时最有名的数学家约翰 伯努利 JohannBernou 1667 1748 的儿子丹尼尔 伯努利 DanidBernoul 1700 1782 提出来的 大意如下 一个人写了 n 封不同的信及相应的 n 个不同的信封 他把这 n 封信都装错了

    2026年3月19日
    5
  • 详解布隆过滤器的原理、优缺点

    详解布隆过滤器的原理、优缺点什么是布隆过滤器?本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilisticdatastructure),特点是高效地插入和查询,可以用来告诉你“某样东西一定不存在或者可能存在”,它是用多个哈希函数,将一个数据映射到位图结构中。此种方式不仅可以提升查询效率,也可以节省大量的内存空间。HashMap的问题讲述布隆过滤器的原理之前,我们先思考一下,通常你判断某…

    2026年4月15日
    9
  • 一文带你了解Redis秒杀应用场景

    一文带你了解Redis秒杀应用场景

    2022年2月20日
    53
  • Spring Boot Configuration Annotation Processor not configured 问题解决

    Spring Boot Configuration Annotation Processor not configured 问题解决问题背景 进行 SpringBoot 配置文件部署时 发出警告 SpringBootCo 但是不影响运行 问题解决方案 在 pom xml 文件中引入依赖 dependency groupId org springframew boot amp l groupId dependency

    2026年3月19日
    1
  • pycharm注册

    pycharm注册激活成功教程 PyCharm 完成注册 1 下载最新版本的 PyCharm2018 3 2 安装完成 官网下载 安装比较简单 不在描述 2 下载 JetbrainsCra release enc jar 包 将此 jar 包放在 PyCharm 安装目录的 bin 文件中 此 jar 包地址 https pan baidu com s 1zwJQzG1hQZ8 记事本打开 PyCharm

    2026年3月27日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号