二叉树之霍夫曼树

news2026/4/2 3:06:08

哈夫曼树(Huffman Tree)是一种用于数据压缩的树形结构,广泛应用于无损数据压缩算法中。由大卫·哈夫曼(David A. Huffman)在1952年提出。它主要用于构造哈夫曼编码,一种基于字符出现频率的变长编码方案。

压缩的目的是使用更少的空间来存储比较大的数据内容。这样首先就要对原数据中重复内容进行统计,重复最多的内容使用最短编码来表示。最短编码对应到树上可以使用节点路径来表示:从根节点到任意一个叶子节点的路径。

这样将重复多的项放于靠近根节点位置,重复最少的尽量存放于最底层叶子节点即可。每个节点位置确定可以根据重复次数作为权重来进行确定。

树的构建:

1、首先统计每个字符在待压缩数据中出现的频率作为节点权重值。

2、将每个字符及其频率(权重)作为叶子节点,构建一个优先队列。

3、从优先队列中取出两个最小权重的节点。创建一个新的内部节点,其权重为这两个节点权重的和,将这两个节点作为新节点的子节点。将新节点插入优先队列。重复上述步骤直到队列中只剩下一个节点,该节点就是哈夫曼树的根节点。

编码生成:

从根节点开始,进行遍历。通常左子节点标记为0,右子节点标记为1。这样可以为每个字符生成一个唯一的二进制编码

代码演示:

首先定义一个Node节点

    class Node<T> {
        T data;
        int weight;
        Node left;
        Node right;
        Node parent;

        public Node(T data,int weight){
            this.data = data;
            this.weight = weight;
        }
    }

Node节点除了必要的引用关系,外还有一个额外必须的属性weight(权重)。

树的构建

    /**
     * 先按权重进行排序
     * 然后拿出两个最小的组成一个树,父节点为两个的权重和构造新节点,然后将这个节点再放入集合中
     * 再拿出两个最小的重复前面的动作,直到集合只有一个元素,则该元素为根元素
     * @param nodeList
     */
    void buildTree(List<Node> nodeList){
        if(nodeList.size() ==1) {
            root = nodeList.get(0);
            return;
        }

        while (nodeList.size() >1){
            nodeList = sort(nodeList);
            Node left = nodeList.remove(0);
            Node right = nodeList.remove(0);

            Node parent = new Node(null,left.weight + right.weight);
            parent.left = left;
            parent.right = right;
            left.parent = parent;
            right.parent = parent;
            nodeList.add(parent);
        }
        root = nodeList.get(0);
    }
    
    List<Node> sort(List<Node> nodeList){
        return nodeList.stream().sorted(Comparator.comparingInt(n -> n.weight)).collect(Collectors.toList());
    }

字符编码获取:

/**
     * 获取字符编码
     * 到左节点路径0,右节点路径为1
     * @param node
     * @return
     */
    String getCode(Node node){
        String code = "";
        Node tmp = node;
        while (tmp.parent != null){
            if(tmp.parent.left == tmp){
                code = "0" + code;
            }else{
                code = "1" + code;
            }
            tmp = tmp.parent;
        }
        return code;
    }

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

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

相关文章

ARCGIS PRO DSK MapTool

MapTool用于自定义地图操作工具&#xff0c;使用户能够在ArcGIS Pro中执行特定的地图交互操作。添加 打开MapTool1.vb文件&#xff0c;可以看到系统已经放出MapTool1类&#xff1a; Public Sub New()将 IsSketchTool 设置为 true 以使此属性生效IsSketchTool TrueSketchTyp…

秋招测评为什么有行测题型?有没有训练题库?

为什么有行测题型&#xff0c;那这就得看看行测题型的作用了。 1、行测题可以比较全面评估应聘者的基本素质&#xff0c;包括数学能力、语言能力、逻辑思维能力等。这些能力是从事各类职业所必需的基本能力&#xff0c;对于判断应聘者的学习潜力和工作效率具有重要意义。 2、…

MySQL基于GTID同步模式搭建主从复制

系列文章目录 rpmbuild构建mysql5.7.42版本的rpm包 文章目录 系列文章目录一、mysql-5.7.42RPM包构建二、同步模式分类介绍1.异步同步模式2.半同步模式2.1.实现半同步操作流程2.2.半同步问题总结2.3.半同步一致性2.4.异步与半同步对比 3.GTID同步 三、GTID同步介绍1.gtid介绍2…

如何准备多台虚拟机并配置集群化软件

在搭建集群化软件的过程中&#xff0c;首先需要准备好多台Linux服务器。本文将详细介绍如何使用VMware提供的克隆功能来准备多台虚拟机&#xff0c;并进行必要的配置以实现集群化软件的部署。 1. 准备多台虚拟机 安装集群化软件&#xff0c;首要条件就是要有多台Linux服务器可…

nvm无法下载npm的问题

1、问题 执行 nvm install 14.21.3 命令&#xff0c;node可以正常下载成功&#xff0c;npm下载失败 2、nvm配置信息 …/nvm/settings.txt root: D:\soft\nvm path: D:\soft\nodejs node_mirror: npmmirror.com/mirrors/node/ npm_mirror: registry.npmmirror.com/mirrors/…

Java面试篇基础部分-Java内部类介绍

首先需要了解什么是内部类,内部类就是定义在类的内部的类称为内部类,内部类可以根据不同的定义方式分为静态内部类、成员内部类、局部内部类和匿名内部类。 静态内部类 定义在类体内部的通过static关键字修饰的类,被称为静态内部类。静态内部类可以访问外部类的静态变量和…

BEV学习---LSS-3--(体素坐标系及各种坐标系的理解)

1、体素坐标系 如下两个链接&#xff0c;详细介绍了对体素坐标系的理解&#xff1a; 体素坐标(voxel_coors)在mmdetection3d中的理解_体素坐标系-CSDN博客 3D目标检测中坐标系详解_点云用的什么坐标系-CSDN博客 2、自动驾驶中各种坐标系的定义及相互转换 【KnowledgeBase】…

lamp和nginx的搭建

lamp搭建 下载需要用到的 yum install php yum install php-mysql yum install php-mbstring 进入到html路径下&#xff0c;将文件复制到该路径 解压文件 将文件夹里的内容都复制到html下 在配置文件中添加页面index.php 此时打开网页提示需添加可写权限 但因为直接添加不…

Java实现发送邮件如何配置SMTP和认证信息?

Java实现发送邮件的关键要点&#xff1f;Java怎么实现邮件发送&#xff1f; Java作为一种强大的编程语言&#xff0c;提供了丰富的库和工具来实现邮件发送功能。AokSend将详细介绍如何在Java中配置SMTP服务器和认证信息&#xff0c;以实现邮件发送功能。 Java实现发送邮件&am…

企业级镜像容器的访问控制

为保障镜像制品及企业版实例安全&#xff0c;需要配置公网的访问控制策略&#xff0c;以限制通过公网访问企业版实例。 ps: 本功能只能在企业版实例使用&#xff0c;对于个人版实例不支持使用此功能。 操作步骤 1、登录容器镜像控制台 &#xff1b; 2、在顶部菜单栏&#xf…

鱼类检测-目标检测数据集(包括VOC格式、YOLO格式)

鱼类检测-目标检测数据集&#xff08;包括VOC格式、YOLO格式&#xff09; 数据集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1B4o8IgOmAWeQJDWpJWxqXg?pwdjaco 提取码&#xff1a;jaco 数据集信息介绍&#xff1a; 共有 2848 张图像和一一对应的标注文件 标注文…

[图论]街道赛跑

题目描述 图一表示一次街道赛跑的跑道。可以看出有一些路口&#xff08;用 0 0 0 到 N N N 的整数标号&#xff09;&#xff0c;和连接这些路口的箭头。路口 0 0 0 是跑道的起点&#xff0c;路口 N N N 是跑道的终点。箭头表示单行道。运动员们可以顺着街道从一个路口移动到…

自测的重要性

1、把debug一遍&#xff0c;看看每一步变量值的变化都符合预期 2、核对需求文档&#xff0c;看看是不是自己的逻辑跟需求都是匹配的&#xff0c;有没有遗漏的细节 3、有时候配合接口的使用方去做点假数据&#xff0c;也是发现自己接口漏洞的好机会 发现了sql少写了个条件、发…

【Go】Go语言中的流程控制语句

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Python识别拖放的PDF文件再转成文本文件

日常工作中经常用到PDF文件&#xff0c;有些PDF文件的文字是不能复制的&#xff0c;为了复制这些文字&#xff0c;我们需要转化PDF文件&#xff0c;或者采用微信的OCR图片识别文字&#xff0c;这样非常不方便。为此&#xff0c;我编写了一个Python小程序&#xff0c;利用Tkinte…

基于51单片机的多功能台灯Protues仿真设计

目录 一、设计背景 二、设计要求 三、仿真演示 四、程序展示 一、设计背景 随着科技的飞速发展和智能家居的普及&#xff0c;传统的台灯已经难以满足现代消费者对照明设备的多样化需求。传统台灯的功能主要集中在提供基本的照明效果&#xff0c;其操作方式通常是通过手动调…

Langchain.js你必须要知道的核心组件

关于Langchain.js Langchain.js&#xff0c;在github上截止到今日已经有92k的start。之前一直偶有耳闻&#xff0c;但没有深入了解。今天看完后&#xff0c;真的是可以堪称大模型里的瑞士军刀。 LangChain由Harrison Chase于2022年10月作为开源软件项目推出&#xff0c;用于连…

抗菌肽;Parasin I;KGRGKQGGKVRAKAKTRSS;CAS号:219552-69-9

【Parasin I 简介】 Parasin I是一种抗菌肽&#xff0c;由19个氨基酸组成&#xff0c;最初从鲶鱼的皮肤粘液中分离得到。它具有广谱的抗菌活性&#xff0c;能够有效对抗革兰氏阳性菌和革兰氏阴性菌&#xff0c;包括一些对传统抗生素具有耐药性的菌株。 【中文名称】抗菌肽 Par…

C语言 11 字符串

前面学习了数组&#xff0c;而对于字符类型的数组&#xff0c;比较特殊&#xff0c;它实际上可以作为一个字符串&#xff08;String&#xff09;表示&#xff0c;字符串就是一个或多个字符的序列&#xff0c;比如在一开始认识的"Hello World"&#xff0c;像这样的多个…

如何编写智能合约——基于长安链的Go语言的合约开发

场景设计&#xff1a;文件存证系统 在数字化时代&#xff0c;文件存证和版本追踪变得越来越重要。设想一个场景&#xff1a;在一个法律事务管理系统中&#xff0c;用户需要提交和管理各种文件的版本记录&#xff0c;以确保每个文件在不同时间点的状态可以被准确追踪。文件可能经…