当前位置: 首页 > news >正文

哈夫曼树

哈夫曼树(Huffman Tree)是一种最优的二叉树,常用于数据压缩,如在 Huffman 编码中使用。它是根据字符出现的频率来构造的,频率越高的字符越靠近树的根,频率低的字符则在较深的节点上。其核心思想是通过构建一颗最小堆(或者优先队列)来逐步合并最小的两个节点,直到所有节点都合并成一颗哈夫曼树。 

哈夫曼树的构建过程:

  1. 统计频率:首先统计每个字符出现的频率。
  2. 构建最小堆:将每个字符作为一个树的节点插入一个最小堆(优先队列)中。
  3. 合并最小频率的节点:每次从最小堆中取出两个频率最小的节点,创建一个新节点,其频率为这两个节点频率之和。然后将这个新节点插入回最小堆。
  4. 重复步骤3,直到堆中只剩下一个节点,这个节点就是哈夫曼树的根节点
#include <iostream>
#include <queue>
#include <vector>
#include <unordered_map>
#include <string>using namespace std;// 哈夫曼树的节点
struct HuffmanNode {char ch;              // 存储字符int freq;             // 字符的频率HuffmanNode* left;    // 左子树HuffmanNode* right;   // 右子树// 构造函数HuffmanNode(char c, int f) : ch(c), freq(f), left(nullptr), right(nullptr) {}// 定义优先级队列的比较规则:按频率最小的优先struct Compare {bool operator()(HuffmanNode* l, HuffmanNode* r) {return l->freq > r->freq; // 返回 true 时 l 排在 r 后面}};
};// 用递归生成哈夫曼编码
void generateHuffmanCodes(HuffmanNode* root, const string& str, unordered_map<char, string>& huffmanCode) {if (root == nullptr)return;// 如果是叶子节点,保存它的编码if (!root->left && !root->right) {huffmanCode[root->ch] = str;}// 遍历左子树和右子树generateHuffmanCodes(root->left, str + "0", huffmanCode);generateHuffmanCodes(root->right, str + "1", huffmanCode);
}// 构造哈夫曼树
HuffmanNode* buildHuffmanTree(const unordered_map<char, int>& freq) {// 优先队列(最小堆)用于按频率排序priority_queue<HuffmanNode*, vector<HuffmanNode*>, HuffmanNode::Compare> minHeap;// 创建叶子节点并插入最小堆for (const auto& pair : freq) {minHeap.push(new HuffmanNode(pair.first, pair.second));}// 合并节点直到只剩一个节点while (minHeap.size() > 1) {// 取出两个最小的节点HuffmanNode* left = minHeap.top(); minHeap.pop();HuffmanNode* right = minHeap.top(); minHeap.pop();// 创建一个新的内部节点,频率为左右节点频率之和HuffmanNode* node = new HuffmanNode('\0', left->freq + right->freq);node->left = left;node->right = right;// 将新节点插入最小堆minHeap.push(node);}// 最后堆中剩下的节点就是哈夫曼树的根节点return minHeap.top();
}// 打印哈夫曼编码
void printHuffmanCodes(const unordered_map<char, string>& huffmanCode) {for (const auto& pair : huffmanCode) {cout << pair.first << ": " << pair.second << endl;}
}int main() {// 输入字符串string text = "this is an example for huffman encoding";// 统计每个字符的频率unordered_map<char, int> freq;for (char c : text) {freq[c]++;}// 构建哈夫曼树HuffmanNode* root = buildHuffmanTree(freq);// 保存每个字符的哈夫曼编码unordered_map<char, string> huffmanCode;// 生成哈夫曼编码generateHuffmanCodes(root, "", huffmanCode);// 打印哈夫曼编码printHuffmanCodes(huffmanCode);return 0;
}

http://www.lryc.cn/news/530429.html

相关文章:

  • wax到底是什么意思
  • 笔记:使用ST-LINK烧录STM32程序怎么样最方便?
  • 数据分析系列--[11] RapidMiner,K-Means聚类分析(含数据集)
  • Python在数据科学领域的深度应用:从数据处理到机器学习模型构建
  • 海外问卷调查渠道查,具体运营的秘密
  • 穷举vs暴搜vs深搜vs回溯vs剪枝系列一>单词搜索
  • 万字长文深入浅出负载均衡器
  • 基于SpringBoot的青年公寓服务平台的设计与实现(源码+SQL脚本+LW+部署讲解等)
  • 经典游戏红色警戒2之英语
  • IM 即时通讯系统-50-[特殊字符]cim(cross IM) 适用于开发者的分布式即时通讯系统
  • QtCreator在配置Compilers时,有一个叫ABI的选项,那么什么是ABI?
  • 处理 **5万字(约7.5万-10万token,中文1字≈1.5-2token)** 的上下文
  • 【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)
  • springboot 启动原理
  • 浅析DDOS攻击及防御策略
  • Linux网络 HTTPS 协议原理
  • Idea插件开发
  • Java 有很多常用的库
  • pytorch实现文本摘要
  • C++基础day1
  • 从TinyZero的数据与源码来理解DeepSeek-R1-Zero的强化学习训练过程
  • 爬虫基础(四)线程 和 进程 及相关知识点
  • 【自开发工具介绍】SQLSERVER的ImpDp和ExpDp工具01
  • 队列—学习
  • SpringBoot的配置(配置文件、加载顺序、配置原理)
  • 如何本地部署DeepSeek?DeepThink R1 本地部署全攻略:零基础小白指南。
  • 陆游的《诗人苦学说》:从藻绘到“功夫在诗外”(中英双语)mastery lies beyond poetry
  • Golang —协程池(panjf2000/ants/v2)
  • 在 crag 中用 LangGraph 进行评分知识精炼-下
  • 基于springboot+vue的哈利波特书影音互动科普网站