【数据结构】哈夫曼树(Huffman Tree)和哈夫曼编码(Huffman Coding)

在这里插入图片描述

哈夫曼树(Huffman Tree)和哈夫曼编码(Huffman Coding)是数据压缩领域常用的技术。哈夫曼树是一种特殊的二叉树,用于构造哈夫曼编码,而哈夫曼编码则是一种变长编码,用于压缩数据。

在解释哈夫曼树和哈夫曼编码之前,我们先来了解一下如何构建哈夫曼树。

  1. 频率统计:首先,需要对待压缩的数据进行频率统计,统计每个字符出现的频率。频率越高的字符,其在哈夫曼编码中的表示越短。

  2. 构建节点:根据统计结果,将每个字符及其对应的频率作为节点。每个节点初始时作为一个独立的子树。

  3. 构建哈夫曼树:重复以下步骤,直到只剩下一个节点:
    a. 选择两个频率最低的节点,合并它们,生成一个新的节点,该节点的频率为两个节点的频率之和。
    b. 将新生成的节点作为子树,再次进行排序。

  4. 哈夫曼树生成:最终,生成的树的根节点即为哈夫曼树的根节点。

一旦构建了哈夫曼树,就可以根据树的结构来生成对应的哈夫曼编码。

  1. 从根节点开始,沿着左子树路径到达叶子节点时,添加一个"0"到编码中;沿着右子树路径到达叶子节点时,添加一个"1"到编码中。

  2. 遍历整棵哈夫曼树,生成每个字符的哈夫曼编码。注意,由于每个字符都能找到唯一的路径,哈夫曼编码是没有前缀的,也就是说,一个字符的哈夫曼编码不是另一个字符的前缀。

通过上述方法,我们就成功地构建了哈夫曼树和哈夫曼编码。接下来,我们可以利用生成的哈夫曼编码来压缩数据。

压缩数据的过程就是将原始数据中的每个字符替换为对应的哈夫曼编码,并将所有替换后的二进制串按位存储。这样,在传输或存储数据时,可以大大减少原始数据的大小。

解压数据的过程相对简单,只需要根据哈夫曼编码和哈夫曼树的对应关系,将编码逐位地进行解码,还原出原始的字符序列。

总结一下,哈夫曼树和哈夫曼编码通过统计字符频率来构建一种具有最优编码的树结构,用于数据压缩和解压缩。通过构建哈夫曼树和生成哈夫曼编码,我们可以将数据压缩到更小的空间,提高数据传输和存储的效率。
以下是一个使用C++面向过程编写的示例代码,展示了如何构建哈夫曼树和生成哈夫曼编码。

#include <iostream>
#include <queue>
#include <map>
using namespace std;// 定义节点结构体
struct Node {char data;int frequency;Node* left;Node* right;
};// 创建节点
Node* createNode(char data, int frequency, Node* left, Node* right) {Node* newNode = new Node();newNode->data = data;newNode->frequency = frequency;newNode->left = left;newNode->right = right;return newNode;
}// 释放节点及其子树的内存
void releaseNode(Node* node) {if (node) {releaseNode(node->left);releaseNode(node->right);delete node;}
}// 定义比较函数用于优先队列排序
struct Compare {bool operator()(const Node* a, const Node* b) {return a->frequency > b->frequency;}
};// 构建哈夫曼树
Node* buildHuffmanTree(map<char, int> frequencies) {priority_queue<Node*, vector<Node*>, Compare> pq;// 将每个字符的频率作为独立节点加入优先队列for (auto pair : frequencies) {Node* newNode = createNode(pair.first, pair.second, nullptr, nullptr);pq.push(newNode);}// 构建哈夫曼树while (pq.size() > 1) {Node* left = pq.top();pq.pop();Node* right = pq.top();pq.pop();int totalFrequency = left->frequency + right->frequency;Node* newNode = createNode('\0', totalFrequency, left, right);pq.push(newNode);}return pq.top();
}// 生成哈夫曼编码
void generateHuffmanCode(Node* root, string code, map<char, string>& huffmanCodes) {if (root == nullptr) {return;}if (root->left == nullptr && root->right == nullptr) {huffmanCodes[root->data] = code;}generateHuffmanCode(root->left, code + "0", huffmanCodes);generateHuffmanCode(root->right, code + "1", huffmanCodes);
}int main() {string input = "hello world";map<char, int> frequencies;// 统计每个字符的频率for (char c : input) {frequencies[c]++;}// 构建哈夫曼树Node* root = buildHuffmanTree(frequencies);// 生成哈夫曼编码map<char, string> huffmanCodes;generateHuffmanCode(root, "", huffmanCodes);// 输出每个字符及其对应的哈夫曼编码for (auto pair : huffmanCodes) {cout << pair.first << " : " << pair.second << endl;}// 释放节点内存releaseNode(root);return 0;
}

以上代码展示了如何通过构建哈夫曼树和生成哈夫曼编码来实现数据的压缩。代码利用优先队列(Priority Queue)来构建哈夫曼树,并使用递归方式生成哈夫曼编码。最后,输出每个字符和其对应的哈夫曼编码。一定要注意在使用完节点后释放相关的内存以避免内存泄漏。

如果你想更深入地了解人工智能的其他方面,比如机器学习、深度学习、自然语言处理等等,也可以点击这个链接,我按照如下图所示的学习路线为大家整理了100多G的学习资源,基本涵盖了人工智能学习的所有内容,包括了目前人工智能领域最新顶会论文合集和丰富详细的项目实战资料,可以帮助你入门和进阶。

链接:

人工智能交流群(大量资料)

在这里插入图片描述

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

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

相关文章

文心一言 VS 讯飞星火 VS chatgpt (147)-- 算法导论12.2 2题

二、用go语言&#xff0c;写出 TREE-MINIMUM 和 TREE-MAXIMUM 的递归版本。 灵捷3.5 。 文心一言&#xff1a; 以下是用 Go 语言编写的树的最大值和最小值的递归版本代码&#xff1a; package main import ( "fmt" ) type TreeNode struct { Val int Le…

【tower-boot 系列】MybatisPlus 集成

Mybatis、MybatisPlus 简单介绍 MybatisPlus 集成 一、pom 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><exclusions><exclusion><groupId>com.zaxxer…

python简单进阶之web框架:fastapi使用教程

原文&#xff1a;python简单进阶之web框架&#xff1a;fastapi使用教程 - 知乎 这是简单进阶教程系列第四篇&#xff0c;本系列文章主要介绍那些可以很快上手的进阶库。 我其实学过一段时间Django框架&#xff0c;但是半途而废了&#xff0c;我觉得可能还是简单一点的框架比较适…

智能优化算法应用:基于象群算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于象群算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于象群算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.象群算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

网络类型解析(基础):探索通信世界的多样面貌

在当今数字化时代&#xff0c;网络已经成为人们生活和工作中不可或缺的一部分。从个人设备之间的直接通信到全球范围的数据传输&#xff0c;不同类型的网络为我们提供了多种连接方式和通信选择。透过对这些网络类型的解析&#xff0c;我们将更好地理解它们的特点、优势和适用场…

JMX的使用

1. 定义和意义 JMX是Java Management Extention的缩写&#xff0c;出发点是让外部通过属性/方法来读取或设置程序状态。对于提供对外服务的程序来说&#xff0c;天生就有这样的能力&#xff0c;Web程序通过HTTP接口对外暴露&#xff0c;RPC应用通过RPC接口暴露。不过带来的问…

ESP32-Web-Server编程- 使用表格(Table)实时显示设备信息

ESP32-Web-Server编程- 使用表格&#xff08;Table&#xff09;实时显示设备信息 概述 上节讲述了通过 Server-Sent Events&#xff08;以下简称 SSE&#xff09; 实现在网页实时更新 ESP32 Web 服务器的传感器数据。 本节书接上会&#xff0c;继续使用 SSE 机制在网页实时显…

深度学习手势识别 - yolo python opencv cnn 机器视觉 计算机竞赛

文章目录 0 前言1 课题背景2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存 5 模型训练5.1 修…

C++模板—函数模板、类模板

目录 一、函数模板 1、概念 2、格式 3、实例化 4、模板参数的匹配 二、类模板 1、定义格式 2、实例化 交换两个变量的值&#xff0c;针对不同类型&#xff0c;我们可以使用函数重载实现。 void Swap(double& left, double& right) {double tmp left;left ri…

黑马一站制造数仓实战1

1. 项目目标 一站制造 企业中项目开发的落地&#xff1a;代码开发 代码开发&#xff1a;SQL【DSL SQL】 SparkCore SparkSQL 数仓的一些实际应用&#xff1a;分层体系、建模实现 2. 内容目标 项目业务介绍&#xff1a;背景、需求 项目技术架构&#xff1a;选型、架构 项目环境…

SpringBootWeb案例_03

Web后端开发_06 SpringBootWeb案例_03 登录认证 智能学习辅助系统登录时需要身份验证 1.登录功能 先实现简单的登录功能&#xff0c;在进一步优化。 1.1需求 若账户或密码不存在/密码不正确&#xff0c;则登录失败。 账户密码正确&#xff0c;则登录成功 1.2接口文档 …

git基本概念

一、版本控制概念 1.1 什么是版本控制 1.1.1 手动管理文件版本 1.1.2 版本控制软件 概念&#xff1a;版本控制软件是一个用来记录文件发生的变化&#xff0c;以便将来查阅特定版本修订情况的系统&#xff0c;有时也叫“版本控制系统”。通俗的理解就是把手工管理文件版本的方…

关于电脑提示vcruntime140_1.dll无法继续执行代码的解决办法

vcruntime140_1.dll是Visual C运行时库的一个组成部分&#xff0c;它包含了大量用于支持C应用程序运行时的功能。这个文件通常在开发和使用C程序时被调用&#xff0c;特别是在使用Microsoft Visual Studio进行开发时。vcruntime140_1.dll文件丢失或损坏会导致C程序无法正常运行…

信息化,数字化,智能化是3种不同概念吗?与机械化,自动化矛盾吗?

先说结论&#xff1a; 1、信息化、数字化、智能化确实是3种不同的概念&#xff01; 2、这3种概念与机械化、自动化并不矛盾&#xff0c;它们是制造业中不同发展阶段和不同层次的概念。 机械化&#xff1a;是指在生产过程中使用机械技术来辅助人工完成一些重复性、单一性、劳…

助力android面试2024【面试题合集】

转眼间&#xff0c;2023年快过完了。今年作为口罩开放的第一年大家的日子都过的十分艰难&#xff0c;那么想必找工作也不好找&#xff0c;在我们android开发这一行业非常的卷&#xff0c;在各行各业中尤为突出。android虽然不好过&#xff0c;但不能不吃饭吧。卷归卷但是还得干…

Pytorch——多卡GPU训练与单卡GPU训练相互切换

部分深度学习网络默认是多卡并行训练的&#xff0c;由于某些原因&#xff0c;有时需要指定在某单卡上训练&#xff0c;最近遇到一个&#xff0c;这里总结如下。 目录 一、多卡训练1.1 修改配置文件1.2 修改主训练文件1.3 显卡使用情况 二、单卡训练2.1 修改配置文件2.2 显卡使…

简单了解下IP的全球划分【笔记】

国际互联网号码分配机构 (The Internet Assigned Numbers Authority&#xff0c;简称IANA&#xff09;。它是互联网名称与数字地址分配机构&#xff08;The Internet Corporation for Assigned Names and Numbers&#xff0c;简称ICANN&#xff09;旗下的一个机构&#xff0c;主…

Linux5-计划任务、进程

计划任务 一、cron 计划任务 周期性计划任务 cron 任务概述 • 用途:按照设置的时间间隔为用户反复执行某一项固定的系统任务 • 软件包&#xff1a;cronie、crontabs • 系统服务&#xff1a;crond • 日志文件&#xff1a;/var/log/crond 管理计划任务策略 • 使用 cro…

存储虚拟化的写入过程

存储虚拟化的场景下&#xff0c;整个写入的过程。 在虚拟机里面&#xff0c;应用层调用 write 系统调用写入文件。write 系统调用进入虚拟机里面的内核&#xff0c;经过 VFS&#xff0c;通用块设备层&#xff0c;I/O 调度层&#xff0c;到达块设备驱动。虚拟机里面的块设备驱动…

uniapp uni-popup组件在微信小程序中滚动穿透问题

起因 在微信小程序中使用uni-popup组件时&#xff0c;出现滚动穿透&#xff0c;并且uni-popup内部内容不会滚动问题。 解决 滚动穿透 查阅官方文档&#xff0c;发现滚动穿透是由于平台差异性造成的&#xff0c;具体解决可以参照文档禁止滚动穿透 <template><page-…