欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > 【数据结构与算法】为通讯电文设计哈夫曼编码 C++实现(映射+优先队列+哈夫曼树)

【数据结构与算法】为通讯电文设计哈夫曼编码 C++实现(映射+优先队列+哈夫曼树)

2025/10/18 22:48:54 来源:https://blog.csdn.net/qq_34988204/article/details/138456634  浏览:    关键词:【数据结构与算法】为通讯电文设计哈夫曼编码 C++实现(映射+优先队列+哈夫曼树)

哈夫曼编码

题目描述

设用于通讯的电文由 n n n个字母组成,给出字母在电文中出现的频率。试为这 n n n个字母设计哈夫曼编码。

输入格式

输入的第一行包含一个整数 n n n,表示字母的数量。

第二行包含 n n n个大写字母,由空格分隔,表示电文中的字母。

第三行包含 n n n个整数,由空格分隔,表示对应字母在电文中出现的频率。

输出格式

输出 n n n行,每行包含一个字母和其对应的哈夫曼编码,用冒号隔开。

样例 #1

样例输入 #1

8
A B C D E F G H
8 10 5 19 30 15 11 28

样例输出 #1

A: 0001
B: 1110
C: 0000
D: 110
E: 10
F: 001
G: 1111
H: 01

思路

首先,定义了一些常量和类型别名。TreeNode 结构体定义了哈夫曼树节点,包含字符数据、左子节点和右子节点。Node 结构体包含频率和哈夫曼树节点,并重载了 < 运算符,用于构建小顶堆。

接着,定义了全局变量 nfacoden 用于存放字符数量,fa 分别用于存放字符和对应的频率,code 用于存放每个字符的哈夫曼编码。

createTreeNode 函数用于创建一个新的哈夫曼树节点。createHuffmanTree 函数用于根据输入的字符和频率创建哈夫曼树。在这个函数中,先将所有字符和对应的频率构造成节点放入优先队列(小顶堆)中,然后每次从堆中取出两个频率最小的节点,创建一个新的节点作为这两个节点的父节点,频率为这两个节点的频率之和,然后将新节点放入堆中。重复这个过程,直到堆中只剩下一个节点,这个节点就是哈夫曼树的根节点。

preorder 函数用于先序遍历哈夫曼树并生成哈夫曼编码。对于非叶子节点,向左遍历时编码添加 “0”,向右遍历时编码添加 “1”。当遇到叶子节点(即字符节点)时,将字符和对应的编码存入 code 中。

printHuffmanCode 函数用于打印所有字符的哈夫曼编码。先调用 preorder 函数生成哈夫曼编码,然后遍历 code 并打印出每个字符和对应的编码。

main 函数先从输入中读取字符数量和每个字符及其频率,然后调用 createHuffmanTree 函数创建哈夫曼树,最后调用 printHuffmanCode 函数打印哈夫曼编码。

算法分析

时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn),其中 n n n 是字符数量。这是因为创建哈夫曼树需要 n − 1 n-1 n1 次插入和删除操作,每次操作的时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)。生成哈夫曼编码的时间复杂度为 O ( n ) O(n) O(n),因为需要遍历所有节点。所以总的时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn)

空间复杂度为 O ( n ) O(n) O(n),其中 n n n 是字符数量。这是因为需要存放所有的字符、频率、哈夫曼树节点和哈夫曼编码。


代码

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#define AUTHOR "HEX9CF"
using namespace std;
using Status = int;
using ElemType = char;const int N = 1e6 + 7;
const int M = 1e3 + 7;
const int TRUE = 1;
const int FALSE = 0;
const int OK = 1;
const int ERROR = 0;
const int INFEASIBLE = -1;
// const int OVERFLOW = -2;struct TreeNode {ElemType data;TreeNode *left, *right;
};
using HuffmanTree = TreeNode *;struct Node {int f;TreeNode *node;bool operator<(const Node &b) const { return f > b.f; }
};int n;
int f[N];
ElemType a[N];
map<char, string> code;TreeNode *createTreeNode(ElemType e, TreeNode *l, TreeNode *r) {TreeNode *t = (TreeNode *)malloc(sizeof(TreeNode));if (!t) {return NULL;}t->data = e;t->left = l;t->right = r;return t;
}HuffmanTree createHuffmanTree(int n, ElemType *a, int *f) {priority_queue<Node> hmin;for (int i = 0; i < n; i++) {TreeNode *t = createTreeNode(a[i], nullptr, nullptr);hmin.push({f[i], t});}while (hmin.size() > 1) {Node a = hmin.top();hmin.pop();Node b = hmin.top();hmin.pop();if (a.f > b.f) {swap(a, b);}TreeNode *t = createTreeNode(' ', a.node, b.node);// cout << a.f << " " << b.f << endl;hmin.push({a.f + b.f, t});}return hmin.top().node;
}void preorder(HuffmanTree T, string c) {if (T) {if (T->data != ' ') {// cout << T->data << ": " << c << endl;code[T->data] = c;return;}preorder(T->left, c + "0");preorder(T->right, c + "1");}
}Status printHuffmanCode(HuffmanTree root) {preorder(root, "");for (const auto i : code) {cout << i.first << ": " << i.second << endl;}return OK;
}int main() {cin >> n;for (int i = 0; i < n; i++) {cin >> a[i];}for (int i = 0; i < n; i++) {cin >> f[i];}HuffmanTree root = createHuffmanTree(n, a, f);printHuffmanCode(root);return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词