哈夫曼树你需要了解一下

news2025/1/18 3:51:36

    • 哈夫曼树介绍
    • 哈夫曼数特点
    • 哈夫曼应用场景
    • 哈夫曼构建过程
    • 哈夫曼树示例
    • 拓展

哈夫曼树介绍

哈夫曼树(Huffman Tree)是一种特殊的二叉树,也被称为最优二叉树。在计算机科学中,它是由权值作为叶子节点构造出来的一种二叉树。哈夫曼树的特点是,对于给定的n个权值,构造出的哈夫曼树具有最小的带权路径长度(WPL)。

具体来说,哈夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码。这个变长编码表是通过评估来源符号出现机率的方法得到的。出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码。这样,编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。

在构建哈夫曼树时,通常规定生成的哈夫曼树中每个结点的左子树根结点的权小于等于右子树根结点的权。对于给定的n个权值,构造出的哈夫曼树有n个叶子结点。

哈夫曼树是由哈夫曼在1951年提出的。当时,他在麻省理工学院(MIT)攻读博士学位,并和修读信息论课程的同学面临选择完成学期报告或期末考试。他的导师罗伯特·法诺出的学期报告题目是:查找最有效的二进制编码。

哈夫曼在研究这个问题的过程中,发现无法证明哪个已有编码是最有效的,因此他转向新的探索,最终发现了基于有序频率二叉树编码的想法,并很快证明了这个方法是最有效的。哈夫曼使用自底向上的方法构建二叉树,避免了次优算法香农-范诺编码(Shannon–Fano coding)的最大弊端──自顶向下构建树。

因为构造这种树的算法是最早由哈夫曼于1952年提出的,所以被称之为哈夫曼树。哈夫曼树是带权路径长度WPL最小的二叉树,它是一种最优二叉树。

在这里插入图片描述

哈夫曼数特点

哈夫曼树的主要特点包括:

  1. 带权路径和最小:哈夫曼树是带权路径和中权值最小的树,也被称为最优二叉树。这意味着在所有可能的二叉树中,哈夫曼树能够使得树的带权路径长度最小。
  2. 不存在度为1的节点:哈夫曼树中不存在度为1的节点,即所有节点都有至少两个子节点。
  3. 总结点数:对于n个叶子节点的哈夫曼树,总共有2n-1个节点。
  4. 权值越小的节点到根节点的路径越长:在哈夫曼树中,权值越小的节点离根节点越远,路径也就越长。
  5. 最优二叉树个数不唯一:由于构建过程中并未严格区分左右子树,所以最优二叉树个数并不唯一。
    除了上述提到的特点外,哈夫曼树还有其他一些特点:
  6. 二叉树:哈夫曼树是一种二叉树,具有二叉树的特性,例如每个节点最多只有两个子节点,且子节点分为左子树和右子树。
  7. 有序树:哈夫曼树是一种有序树,左子树和右子树是有顺序的,次序不能任意颠倒。这也意味着即使某个节点只有一个子节点,也需要区分它是左子树还是右子树。
  8. 构建过程:哈夫曼树的构建过程通常采用优先队列的方式,将权值最小的两个节点合并为一个新的节点,然后将新节点的权值加入到优先队列中。这个过程会不断重复,直到优先队列中只剩下一个节点为止。
  9. 动态构建:哈夫曼树也可以动态构建,即每次只处理一部分数据,然后根据处理结果动态地构建哈夫曼树。这种构建方式可以更加灵活地处理数据,并且可以实时地更新哈夫曼树。
  10. 应用广泛:哈夫曼树被广泛应用于各种领域,例如数据压缩、编码解码、序列比对、机器学习、图像处理和声音处理等。

在这里插入图片描述

哈夫曼应用场景

哈夫曼树是一种广泛使用的数据结构,主要用于构建最优编码,在许多领域都有应用。

1. 数据压缩 :哈夫曼编码是一种无损数据压缩方法,通过使用较短的编码来表示常见的符号,从而减少数据的大小。它被广泛应用于图像、音频和视频等数据的压缩。
2. 编码解码 :哈夫曼树可以用于构建最优编码,将信息转换为二进制形式,并可以在接收端使用相同的哈夫曼树解码恢复原始信息。这种编码解码技术被广泛应用于通信和网络传输领域。
3. 序列比对 :在生物信息学中,哈夫曼树被用于DNA序列的比对和相似度计算。通过构建基因序列的哈夫曼树,可以比较不同基因序列之间的相似性和差异。
4. 机器学习 :哈夫曼树也被用于机器学习算法中,例如决策树和聚类算法。通过构建特征的哈夫曼树,可以优化特征选择和分类器的构建。
5. 图像处理 :哈夫曼树可以用于图像的压缩和编码,以及图像特征提取和分类。
6. 声音处理 :哈夫曼树可以用于声音的压缩和编码,以及语音识别和合成。
7. 优化技术 :哈夫曼树是一种优化技术,可以用于解决各种优化问题,例如最短路径问题、最小生成树问题等。

哈夫曼树在许多领域都有广泛的应用,是一种非常实用的数据结构和算法。

在这里插入图片描述

哈夫曼构建过程

哈夫曼树的构建过程如下:

  1. 准备阶段:给定N个权值作为N个叶子结点,构造一棵二叉树,该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。
  2. 创建阶段:给定n个权值,构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:
  • a. 将w1、w2、…,wn看成是有n棵树的森林(每棵树仅有一个结点);

  • b. 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;

  • c. 从森林中删除选取的两棵树,并将新树加入森林;

  • d. 重复b、c步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。

在这里插入图片描述

哈夫曼树示例

以下是使用Java实现哈夫曼树的示例代码:

import java.util.*;

class Node {
    int weight;
    Node left, right;

    Node(int weight) {
        this.weight = weight;
        left = right = null;
    }
}

class HuffmanTree {
    private static final int R = 2; // 哈夫曼树中每个节点的左子树和右子树的数量

    private Node root; // 根节点

    // 构建哈夫曼树
    public void build(int[] weights) {
        int[] queue = new int[weights.length]; // 存储节点的索引
        for (int i = 0; i < weights.length; i++) {
            queue[i] = i + 1; // 将节点的索引加入队列
        }
        PriorityQueue<Node> pq = new PriorityQueue<>(R); // 使用优先队列存储节点
        for (int i = 0; i < weights.length; i++) {
            Node node = new Node(weights[i]); // 创建新节点
            pq.offer(node); // 将节点加入优先队列
            if (pq.size() > R) { // 如果优先队列中的元素数量超过R,则合并两个最小节点
                Node min1 = pq.poll(); // 取出最小节点1
                Node min2 = pq.poll(); // 取出最小节点2
                Node parent = new Node(min1.weight + min2.weight); // 创建父节点
                parent.left = min1; // 设置左子树
                parent.right = min2; // 设置右子树
                pq.offer(parent); // 将父节点加入优先队列
            }
            if (i == weights.length - 1) { // 如果遍历完所有节点,则根节点为当前队列中最大的节点
                root = pq.poll();
            }
        }
    }
}

优先队列在构建哈夫曼树时的作用是维护和调整节点的优先级。优先队列中的节点按照其权值的大小进行排序,权值最小的节点位于队列的前端。每次从队列中取出权值最小的两个节点,将它们合并为一个新的节点,新的节点的权值等于这两个节点的权值之和。然后将新的节点重新插入到优先队列中。这个过程不断重复,直到优先队列中只剩下一个节点,这个节点就是构建出的哈夫曼树的根节点。
通过使用优先队列,我们可以高效地找到权值最小的两个节点,并快速地合并它们。这是因为在优先队列中,权值最小的节点始终位于队列的前端,我们可以直接取出这两个节点进行合并。这极大地简化了构建哈夫曼树的过程,并提高了效率。

在这里插入图片描述

拓展

AVL树你需要了解一下

红黑树你需要了解一下

满二叉树你需要了解一下

完全二叉树你需要了解一下

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1239391.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机组成原理(万字爆肝整理)

第一章 计算机系统概述 “较简单&#xff0c;不做过多赘述&#xff0c;后面会详细学到” 第一节 计算机系统层次结构 1.计算机系统的基本组成&#xff1a;硬件软件 2.计算机硬件的基本组成&#xff1a;运算器存储器控制器输入设备输出设备 3.系统软件和应用软件 系统软件…

企业数字化转型所需的数据在哪里找?企业数据运营有什么用?

现阶段&#xff0c;越来越多企业考虑数字化转型。特别是中小型企业&#xff0c;他们察觉到&#xff1a;数字化转型的关键在于数据的运营。只有通过数据的有效管理和不断挖掘&#xff0c;企业才可以更好地了解市场需求&#xff0c;优化业务流程&#xff0c;提高决策效率&#xf…

浅谈Python装饰器原理与用法分析

前言 本文实例讲述了Python装饰器原理与用法。分享给大家供大家参考&#xff0c;具体如下&#xff1a; 1、装饰器的本质是函数&#xff0c;主要用来装饰其他函数&#xff0c;也就是为其他函数添加附加功能 2、装饰器的原则: (1) 装饰器不能修改被装饰的函数的源代码 (2) 装…

磐舟CI使用说明及案例

整体介绍 磐舟作为一个devops产品&#xff0c;它具备基础的CI流水线功能。同时磐舟的流水线是完全基于云原生架构设计的&#xff0c;在使用时会有一些注意事项。这里首先我们要了解磐舟整体的流水线打包逻辑。 文档结构说明 一般来说&#xff0c;磐舟推荐单个业务的标准git库…

面试官:什么是三色标记

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

sqlserver==索引解析,执行计划,索引大小

1创建测试表 -- 创建大型表 CREATE TABLE LargeTableWithIndex (ID int IDENTITY(1,1) PRIMARY KEY,IndexedColumn int,NonIndexedColumn nvarchar(255),OtherData nvarchar(255) );2插入测试数据 -- 使用 T-SQL 插入大量数据 DECLARE @i int = 1; WHILE @i <= 100000 -- …

优先经验回放(prioritized experience replay)

prioritized experience replay 思路 优先经验回放出自ICLR 2016的论文《prioritized experience replay》。 prioritized experience replay的作者们认为&#xff0c;按照一定的优先级来对经验回放池中的样本采样&#xff0c;相比于随机均匀的从经验回放池中采样的效率更高&…

第一百七十六回 如何创建渐变色边角

文章目录 1. 概念介绍2. 实现方法3. 代码与细节3.1 示例代码3.2 代码细节 4. 内容总结 我们在上一章回中介绍了"如何创建放射形状渐变背景"相关的内容&#xff0c;本章回中将介绍"如何创建渐变色边角".闲话休提&#xff0c;让我们一起Talk Flutter吧。 1.…

2023年【广东省安全员B证第四批(项目负责人)】报名考试及广东省安全员B证第四批(项目负责人)复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 广东省安全员B证第四批&#xff08;项目负责人&#xff09;报名考试是安全生产模拟考试一点通总题库中生成的一套广东省安全员B证第四批&#xff08;项目负责人&#xff09;复审考试&#xff0c;安全生产模拟考试一点…

智能安全帽作业记录仪赋能智慧工地人脸识别劳务实名制

需求背景 建筑工地是一个安全事故多发的场所。目前&#xff0c;工程建设规模不断扩大&#xff0c;工艺流程纷繁复杂&#xff0c;如何完善现场施工现场管理&#xff0c;控制事故发生频率&#xff0c;保障文明施工一直是施工企业、政府管理部门关注的焦点。尤其随着社会的不断进…

18.天气小案例

1►新增带Layout组件的页面 直接在views文件夹下面新增weather.vue。然后随便写一个123&#xff0c;现在先让我们页面能跳过去先。 让页面能跳过去&#xff0c;有好几种方法&#xff1a; 1、在菜单管理自己添加一个菜单&#xff0c;然后把菜单分配给某个角色&#xff0c;再把…

【Python进阶】近200页md文档14大体系第4篇:Python进程使用详解(图文演示)

本文从14大模块展示了python高级用的应用。分别有Linux命令&#xff0c;多任务编程、网络编程、Http协议和静态Web编程、htmlcss、JavaScript、jQuery、MySql数据库的各种用法、python的闭包和装饰器、mini-web框架、正则表达式等相关文章的详细讲述。 Python全套笔记直接地址…

【iOS】实现评论区展开效果

文章目录 前言实现行高自适应实现评论展开效果解决cell中的buttom的复用问题 前言 在知乎日报的评论区中&#xff0c;用到了Masonry行高自适应来实现评论的展开&#xff0c;这里设计许多控件的约束问题&#xff0c;当时困扰了笔者许久&#xff0c;特此撰写博客记录 实现行高自…

GB28181学习(十七)——基于jrtplib实现tcp被动和主动发流

前言 GB/T28181-2022实时流的传输方式介绍&#xff1a;https://blog.csdn.net/www_dong/article/details/134255185 基于jrtplib实现tcp被动和主动收流介绍&#xff1a;https://blog.csdn.net/www_dong/article/details/134451387 本文主要介绍下级平台或设备发流功能&#…

微信小游戏上线流程

微信小游戏上线是一个需要经过一系列步骤的过程。以下是一个一般性的微信小游戏上线流程&#xff0c;请注意&#xff0c;上述步骤可能会有微信平台的政策和规定的变化&#xff0c;因此建议在开发过程中及时查阅微信小游戏的官方文档和最新政策。北京木奇移动技术有限公司&#…

DB2—03(DB2中常见基础操作)

DB2—03&#xff08;DB2中常见基础操作&#xff09; 1. 前言1.1 oracle和mysql相关 2. db2中的"dual"2.1 SYSIBM.SYSDUMMY12.2 使用VALUES2.3 SYSIBM.SYSDUMMY1 "变" dual 3. db2中常用函数3.1 nvl()、value()、COALESCE()3.2 NULLIF() 函数3.3 LISTAGG() …

含分布式电源的配电网可靠性评估matlab程序

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 参考文献&#xff1a; 基于仿射最小路法的含分布式电源配电网可靠性分析——熊小萍 主要内容&#xff1a; 通过概率模型和时序模型分别进行建模&#xff0c;实现基于概率模型最小路法的含分布式电源配电网…

Python BDD之Behave测试报告

behave 本身的测试报告 behave 本身提供了四种报告格式&#xff1a; pretty&#xff1a;这是默认的报告格式&#xff0c;提供颜色化的文本输出&#xff0c;每个测试步骤的结果都会详细列出。plain&#xff1a;这也是一种文本格式的报告&#xff0c;但没有颜色&#xff0c;并且…

【C++】泛型编程 ⑫ ( 类模板 static 关键字 | 类模板 static 静态成员 | 类模板使用流程 )

文章目录 一、类模板使用流程1、类模板 定义流程2、类模板 使用3、类模板 函数 外部实现 二、类模板 static 关键字1、类模板 static 静态成员2、类模板 static 关键字 用法3、完整代码示例 将 类模板 函数声明 与 函数实现 分开进行编码 , 有 三种 方式 : 类模板 的 函数声明…

超详细!新手必看!STM32-通用定时器简介与知识点概括

一、通用定时器的功能 在基本定时器功能的基础上新增功能&#xff1a; 通用定时器有4个独立通道&#xff0c;且每个通道都可以用于下面功能。 &#xff08;1&#xff09;输入捕获&#xff1a;测量输入信号的周期和占空比等。 &#xff08;2&#xff09;输出比较&#xff1a;产…