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

构造哈夫曼树的算法_哈夫曼树的应用数据结构一、什么是赫夫曼树给定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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 达梦数据库的函数_达梦数据库连接命令

    达梦数据库的函数_达梦数据库连接命令SQL工作笔记-达梦数据库关于时间的函数http://blog.itpub.net/69995127/viewspace-2758308/达梦数据库的查询以及函数的使用

    2022年10月28日
  • 使用Zookeeper实现选举

    使用Zookeeper实现选举

    2021年6月7日
  • pycharm+anaconda安装教程_anaconda配置pycharm

    pycharm+anaconda安装教程_anaconda配置pycharm对了宝贝儿们,卑微小李的公众号【野指针小李】已开通,期待与你一起探讨学术哟~摸摸大!目录1WhyAnaconda?2Anaconda安装流程2.1卸载python2.2下载anaconda2.2安装anaconda1WhyAnaconda?Anaconda最大的优势我认为在于可以做环境管理,可以通过创建不同的环境,安装不同的包。简单来说,就比如我们在github上下载了一个代码,是用python2.6写的,但是我们的python是3.7的版本。如果我们没有用anaconda,那么我们

    2022年8月27日
  • serdes接口速率_通用串行接口

    serdes接口速率_通用串行接口在以往的IC之间的源同步当中,发送的信号包括数据流信号,以及随着数据流信号同步的时钟信号,时钟信号在低速传输的情况下:1G以下传输,外部的扰动以及时钟抖动不会太影响数据流的恢复,但是如果时钟信号突破了1G甚至更高的情况下,外界环境中比如EMI的各种影响会引起时钟发生抖动,在高速采样恢复的过程中,这就没办法使用该时钟信号恢复数据,这里就用到了高速Serdes串行接口的恢复办法,将数据和时钟都通过高速线上传输,然后接受端通过PLL从数据流中恢复时钟,即使在传输的线上有轻微抖动,但是时钟和数据同时…

    2022年10月31日
  • python递归函数讲解_Python递归函数实例讲解

    python递归函数讲解_Python递归函数实例讲解Python递归函数实例讲解Python递归函数实例1、打开Python开发工具IDLE,新建‘递归.py’文件,并写代码如下:defdigui(n):ifn==0:print(”)returnprint(‘*’*n)digui(n-1)if__name__==’__main__’:digui(5)这里递归打印*号,先打印后递归2、F5运行程序,打印内容如下;********…

    2022年10月25日
  • pytest fixtures_pytest命令

    pytest fixtures_pytest命令fixture的优势Pytest的fixture相对于传统的xUnit的setup/teardown函数做了显著的改进:命名方式灵活,不局限于setup和teardown这几个命名conf

    2022年7月31日

发表回复

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

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