数据结构 —— 哈夫曼树

news2024/10/6 0:23:42

数据结构 —— 哈夫曼树

  • 哈夫曼树
      • 定义
      • 构造算法
      • 特性
      • 应用
  • 哈夫曼编码
      • 核心概念
      • 工作原理
      • 特点

我们今天来看哈夫曼树

哈夫曼树

哈夫曼树(Huffman Tree),是一种特殊的二叉树,由D.A. Huffman在1952年提出,主要用于数据压缩,特别是哈夫曼编码(Huffman Coding)中。以下是关于哈夫曼树的全面概念:

定义

哈夫曼树是一种带权路径长度最短的二叉树,也称为最优二叉树。它是在给定一组具有不同权重的叶子节点(通常代表数据中的符号或字符)的情况下,通过特定的构建算法得到的。该树的特点是,所有叶子节点位于最底层或倒数第二层,且没有度为1的节点(除了根节点可能外),同时保证了从根节点到任何叶子节点的路径上的权值之和(即带权路径长度)最小。

举个例子:
在这里插入图片描述
在这里插入图片描述

构造算法

  1. 初始化:将每个权重作为一个叶子节点,放入一个优先队列(优先级基于节点权重,通常使用最小堆实现)。
  2. 合并节点:从队列中取出两个权重最小的节点,创建一个新的内部节点,其权重为这两个节点的权重之和,新节点作为这两个节点的父节点。
  3. 重复步骤2:将新创建的节点放回优先队列,重复上述过程,直到队列中只剩下一个节点,该节点即为哈夫曼树的根节点。
  4. 生成编码:从根到每个叶子节点的路径可以转化为一个唯一的二进制字符串(路径上向左走记为0,向右走记为1),这个字符串就是该叶子节点代表的字符的哈夫曼编码。

在这里插入图片描述这里我没有写得那么复杂,我用一个vector维护森林,并且排好序,然后依次拿出构造哈夫曼树:

#pragma once
#include<algorithm>
#include<iostream>
#include<vector>

// 定义霍夫曼树节点结构体
template<class T>
struct HuffManTreeNode
{
public:
    // 构造函数,初始化节点数据、左孩子和右孩子
    HuffManTreeNode(T data)
            :_data(data)
            , _leftchild(nullptr)
            , _rightchild(nullptr)
    {

    }

    // 拷贝构造函数,用于复制已有节点的信息
    HuffManTreeNode(HuffManTreeNode<T>* node)
            :_data(node->_data)
            , _leftchild(node->_leftchild)
            , _rightchild(node->_rightchild)
    {

    }

    // 析构函数
    ~HuffManTreeNode()
    {

    }

    // 创建新节点并返回指针
    HuffManTreeNode<T>* CreateNode(T data)
    {
        HuffManTreeNode<T>* newnode = new HuffManTreeNode(data);
        return newnode;
    }

    // 根据已有节点创建新节点并返回指针
    HuffManTreeNode<T>* CreateNode(HuffManTreeNode<T>* node)
    {
        HuffManTreeNode<T>* newnode = new HuffManTreeNode(node);
        return newnode;
    }

    // 向树中插入新节点
    void Insert(HuffManTreeNode<T>*& node, T data)
    {
        HuffManTreeNode<T>* newnode = CreateNode(data);

        if (newnode == nullptr)
        {
            perror("new fail");
            return;
        }

        if (node->_leftchild == nullptr)
        {
            node->_leftchild = newnode;
        }
        else if (node->_rightchild == nullptr)
        {
            node->_rightchild = newnode;
        }

        return;
    }

    // 向树中插入已有节点
    void Insert(HuffManTreeNode<T>*& node, HuffManTreeNode<T>* temp)
    {
        if (node->_leftchild == nullptr)
        {
            node->_leftchild = CreateNode(temp);
        }
        else if (node->_rightchild == nullptr)
        {
            node->_rightchild = CreateNode(temp);
        }
        return;
    }

    // 重载赋值运算符
    HuffManTreeNode<T>& operator=(const HuffManTreeNode<T>* node)
    {
        if (this == node)
        {
            return *this;
        }

        _data = node->_data;
        _leftchild = node->_leftchild;
        _rightchild = node->_rightchild;

        return *this;
    }

    // 数据成员
    T _data;
    // 左右孩子指针
    HuffManTreeNode<T>* _leftchild;
    HuffManTreeNode<T>* _rightchild;
};

// 中序遍历霍夫曼树
template<class T>
void Inorder(HuffManTreeNode<T>* node)
{
    if (node == nullptr)
    {
        return;
    }

    Inorder(node->_leftchild); // 遍历左子树
    std::cout<< node->_data << " "; // 访问当前节点
    Inorder(node->_rightchild); // 遍历右子树
}
#include"Huffman.h"

int main()
{
   std::vector<int> vt = {1,45,12,56,78,0,1,3};
   std::sort(vt.begin(),vt.end());

   for(auto e : vt)
   {
       std::cout << e << " ";
   }

   std::cout<<std::endl;

   //创建哈夫曼树
   HuffManTreeNode<int>* node = new HuffManTreeNode(vt[0]+vt[1]);

   node->Insert(node,vt[0]);
   node->Insert(node,vt[1]);

   for(int i = 2 ; i < vt.size(); i++)
   {
       HuffManTreeNode<int>* temp = node;

       node = node->CreateNode(node->_data +vt[i]);

       node->Insert(node,temp);
       node->Insert(node,vt[i]);
   }

   Inorder(node);

   return 0;
}

在这里插入图片描述

特性

  • 最优性:在所有叶子节点数量相同且节点权值已知的二叉树中,哈夫曼树的带权路径长度是最小的。
  • 编码效率:哈夫曼编码根据字符出现的频率分配编码,高频字符的编码较短,低频字符的编码较长,从而在整体上达到高效的数据压缩效果。
  • 无损编码:哈夫曼编码是一种无损数据压缩方法,可以完全恢复原始数据。
  • 自适应性:虽然经典哈夫曼编码基于静态概率模型,但存在变体如自适应哈夫曼编码,能够根据数据流动态调整编码表,适用于数据统计特性随时间变化的情况。

应用

  • 数据压缩:广泛应用于文本、图像、音频等数据的无损压缩。
  • 通信系统:优化数据传输,减少带宽需求。
  • 文件存储:减小文件大小,节约存储空间。
  • 编译器:用于词法分析中的关键字识别,通过为常用关键字分配较短编码,提高解析速度。

哈夫曼编码

哈夫曼编码(Huffman Coding)是一种高效的熵编码(Entropy Encoding)方法,用于无损数据压缩。它是基于哈夫曼树(Huffman Tree)构造的一种数据编码方式,由David A. Huffman在1952年提出。以下是哈夫曼编码的核心概念、工作原理以及特点:

核心概念

哈夫曼编码的基本思想是根据数据中各个符号(如字符、像素值等)出现的频率来为它们分配不同的编码,出现频率高的符号分配较短的编码,而频率低的符号则分配较长的编码。这样,当整个数据集被编码时,由于高频符号使用的短编码能频繁重复,从而实现整体数据量的压缩。

工作原理

  1. 频率统计:首先统计待编码数据中每个符号出现的频率。
  2. 构建哈夫曼树:使用频率作为权重,通过哈夫曼树的构造算法(见前述哈夫曼树的构造过程),构建一棵二叉树。在这个过程中,每次都将两个最小频率的节点合并成一个新的节点,新节点的频率是两个子节点频率之和。
  3. 生成编码:从哈夫曼树的根到每个叶子节点的路径定义了该叶子节点代表符号的编码。具体来说,向左分支时编码添加一个“0”,向右分支时添加一个“1”。因此,叶子节点越深,其对应的编码就越长。
  4. 编码数据:使用生成的哈夫曼编码表对原始数据进行编码,即将数据中的每个符号替换为其对应的编码字符串。

特点

  • 无损编码:哈夫曼编码是一种无损数据压缩技术,意味着解码后可以完全恢复原始数据。
  • 自适应性:虽然标准哈夫曼编码需要预先知道数据的概率分布,但可以通过动态哈夫曼编码技术,在不知道全部数据的情况下逐步更新编码表,适应数据流的变化。
  • 效率:在所有前缀编码(即任意编码都不会是另一个编码的前缀)中,哈夫曼编码提供了理论上的最优平均编码长度,即熵的上限。
  • 简单性:尽管编码效率高,哈夫曼编码的算法实现相对直接且易于理解。

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

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

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

相关文章

如何选择适合的接口自动化测试工具!

引言&#xff1a; 在现代软件开发中&#xff0c;接口自动化测试已经成为保证软件质量的重要环节。通过自动化测试工具&#xff0c;可以有效地提高测试效率、减少人力成本&#xff0c;并且能够更好地发现和解决潜在的问题。然而&#xff0c;面对众多的接口自动化测试工具&#…

电子设备抗震等级与电子设备震动实验

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/139923445 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软…

机器学习之支持向量机丨神经网络测试

选择题 SVM中的什么是支持向量&#xff1f; 【 正确答案: D】 A. 数据集中的所有样本 B. 模型参数 C. 模型的预测输出 D. 训练数据中离决策边界最近的样本点 支持向量机(SVM)算法的主要目标是&#xff1a; 【 正确答案: C】 A. 最小化间隔 B. 最小化损失函数 C. 最大化间隔 D.…

Redis-主从复制的准备工作-准备三台redis服务器

文章目录 1、新建三个redis配置文件&#xff0c;用于定义每个服务的专属配置1.1、复制文件redis.conf到redis安装目录下1.2、关闭redis_common.conf中的 aof 功能1.1.1、新建 redis_6379.conf1.1.2、新建 redis_6380.conf1.1.3、新建 redis_6381.conf 2、启动三个服务器2.1、后…

游戏行业新质生产力洞察报告 | 七成游戏企业技术投入显著增加 AI应用率99%

近日&#xff0c;伽马数据发布了《中国游戏产业新质生产力发展报告》。报告围绕中国游戏产业推动“新质生产力”发展的关键路径和重点领域进行深入讨论&#xff0c;并通过对相关数据和典型案例的深入分析&#xff0c;清晰呈现当前中国游戏企业在发展新质生产力过程中的探索与实…

打造智慧矿山:整体架构设计与实践探索

随着信息技术的不断发展&#xff0c;智慧矿山作为矿业领域的创新模式&#xff0c;正日益受到关注。在智慧矿山中&#xff0c;先进的传感器、大数据分析、人工智能等技术被广泛应用&#xff0c;以提高矿山生产效率、降低成本&#xff0c;并确保安全环保。本文将深入探讨智慧矿山…

2.5 MAC扫描器

MAC扫描器是一款专门用来获取网卡物理地址的网络管理软件&#xff0c;相对于Windows系统的getmac命令&#xff0c;MAC扫描器功能更加强大&#xff0c;它不仅可以获取局域网计算机的MAC地址&#xff0c;还可以获取 Internet 中网卡的MAC地址。MAC扫描器通常被用来管理本地网络中…

炸锅!张宇25强化咋样?听说书厚到爆炸?

网上已经炸锅了&#xff01;都说学不完了。 但是&#xff0c;网上的几个主流观点&#xff0c;不完全对。 观点1: 基础30讲没变。强化36讲换汤不换药。 知能行 AI 教练认为&#xff0c;不完全对。基础30讲书没变&#xff0c;但课变了。课时比24多出2倍。 这是因为&#xff0c…

GWB—200JA型引伸计标定器

GWB一200JA型引伸计标定器&#xff0c;是一种纯机械式的高精度位移测微仪器。依据JJG762—2007引伸计检定规程要求&#xff0c;专门用于对各类引伸计的标定&#xff0c;也广泛用于位移传感器的检定及相应百分表、千分表的标定。 l、本仪器由精密微分测头及测量支架组成。该标定…

NAPI篇【1】——如何创建含NAPI的OpenHarmony工程

笔者从事OpenHarmony的北向应用开发&#xff0c;关于NAPI的应用这里做一个笔记总结&#xff0c;包含NAPI的OpenHarmony工程的创建、cpp文件详解、如何编写NAPI函数等&#xff0c;都是基于笔者的开发经验和网上参考资料汇集而成&#xff0c;笔者也处于学习阶段&#xff0c;如有错…

佳裕达物流:披露风险,负债1.26亿,营收下滑,净利润下滑-5925.93%

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 一、佳裕达物流公司介绍 佳裕达物流成立于2009年&#xff0c;总部位于广东省深圳市&#xff0c;是中国领先的端到端供应链解决方案供应商之一。 现已发展成为立足粤港澳大湾区、面向全国、布局全球的大型AAAA级综合服务型…

基于 Native 技术加速 Spark 计算引擎

本文整理自 2024 年 6 月 DataFunSummit 2024 OLAP 架构峰会 Lakehouse 湖仓一体化架构论坛的同名主题分享。 今天分享的主题是基于 Native 技术加速 Spark 计算引擎&#xff0c;大家将会了解到如何基于 ClickHouse 来改造 Spark 引擎&#xff0c;最终获得较为可观的性能提升。…

对于todesk共享剪切板不好用的问题记录

todesk 远程复制粘贴 共享剪切版 1.对于已经开启todesk里面的共享剪切板设置的2. 如果此时仍不能远程复制粘贴&#xff0c;可以考虑查看快捷键映射的问题 1.对于已经开启todesk里面的共享剪切板设置的 2. 如果此时仍不能远程复制粘贴&#xff0c;可以考虑查看快捷键映射的问题 …

计算机网络 —— 网络字节序

网络字节序 1、网络字节序 (Network Byte Order)和本机转换 1、大端、小端字节序 “大端” 和” 小端” 表示多字节值的哪一端存储在该值的起始地址处&#xff1b;小端存储在起始地址处&#xff0c;即是小端字节序&#xff1b;大端存储在起始地址处&#xff0c;即是大端字节…

分类预测 | ZOA-PCNN-AT-SVM斑马优化并行卷积-支持向量机融合注意力机制的故障识别

分类预测 | ZOA-PCNN-AT-SVM斑马优化并行卷积-支持向量机融合注意力机制的故障识别 目录 分类预测 | ZOA-PCNN-AT-SVM斑马优化并行卷积-支持向量机融合注意力机制的故障识别分类效果基本描述程序设计参考资料 分类效果 基本描述 1.ZOA-PCNN-AT-SVM斑马优化并行卷积-支持向量机融…

昇思25天学习打卡营第1天|FCN图像语义分割》

全卷积网络&#xff08;Fully Convolutional Networks&#xff0c;FCN&#xff09;是UC Berkeley的Jonathan Long等人于2015年在Fully Convolutional Networks for Semantic Segmentation一文中提出的用于图像语义分割的一种框架。 论文地址&#xff1a;https://arxiv.org/pdf…

【云计算 复习】第6节 AWS亚马逊

一、基础存储架构Dynamo 1.概述 &#xff08;1&#xff09;为了保证其稳定性&#xff0c;Amazon的系统采用完全的分布式、去中心化的架构。 &#xff08;2&#xff09;Dynamo只支持简单的键值对方式的数据存储&#xff0c;不支持复杂的查询 &#xff08;3&#xff09;Dynamo中…

揭秘未来艺术:AI绘画工具全面介绍

&#x1f4d1;前言 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经逐渐渗透到我们生活的方方面面。在艺术创作领域&#xff0c;AI技术同样展现出了其独特的魅力。今天&#xff0c;我们就来一起探索这个神秘而引人入胜的领域&#xff0c;深入了解AI绘画…

车联网全方位安全适配与领先架构

设想一下如下场景&#xff1a; 您钟爱的座驾&#xff0c;在毫无外力破坏迹象的情况下&#xff0c;突然被侵入&#xff0c;远程启动&#xff0c;然后绝尘而去… 别以为这只是大银幕上的虚构桥段&#xff0c;事实上&#xff0c;这一幕在现实中已经上演。 某款备受欢迎的车型&a…

【数列极限证明大题】解题方法,证明数列极限存在并求此极限,单调有界准则

文章目录 数列极限证明大题1.单调有界准则1.1 证有界性和单调性 1.2真题实战1.2 证明有界性中常用到的不等式 写在最前&#xff0c;持续更新中 数列极限证明大题 数列极限的证明大题的目标是&#xff0c;证明数列极限存在且求此极限。 核心方法是&#xff1a;单调有界准则&…