#include<iostream> #include<string.h> #define MAXSIZE 100 using namespace std; typedef struct {//哈夫曼树结点的形式 int weight; //结点的权值 int parent,lchild,rchild; //结点的双亲、左孩子、右孩子的下标 }HTNode,*HuffmanTree; //动态分配数组存储哈夫曼树 typedef char **HuffmanCode; //定义编码表类型 int Search(char a[],char ch) {//查找数组中字符ch所在的位置,返回数组下标,否则返回-1 for(int i=0;a[i]!='\0';i++) { if(a[i]==ch) return i; } return -1; } void Sort(char a[],int b[],int len) {//按ASCII码冒泡排序 /**************begin************/ for(int i=0; i<len-1; i++) { for(int j=0; j<len-1-i; j++) { if(a[j]>a[j+1]) } } /**************end************/ } void Select_min(HuffmanTree HT,int n,int &s1,int &s2) {// 在HT[k](1≤k≤i-1)中选择两个其双亲域为0且权值最小的结点,并返回它们在HT中的序号s1和s2 /**************begin************/ /**************end************/ } int m; void CreateHuffmanTree(HuffmanTree &HT,int n,int b[]) {//构造哈夫曼树HT /**************begin************/ /**************end************/ } void Cre
时间: 2025-05-24 14:00:12 浏览: 21
### 哈夫曼树编码的 C++ 实现
以下是基于哈夫曼树构建并生成对应编码的一个完整 C++ 示例代码。此代码涵盖了创建哈夫曼树的过程以及如何通过遍历该树来获得字符对应的哈夫曼编码。
#### 构建哈夫曼树的核心逻辑
为了实现哈夫曼树及其编码功能,通常需要定义节点结构体 `TreeNode` 和存储这些节点的数组。随后按照权重从小到大排列节点,并逐步合并两个最小权重的节点形成新的父节点,直到只剩下一个根节点为止[^1]。
```cpp
#include <iostream>
#include <vector>
#include <queue>
#include <string>
using namespace std;
// 定义哈夫曼树节点
struct TreeNode {
char ch; // 字符
int weight; // 权重(频率)
TreeNode* lchild; // 左子节点指针
TreeNode* rchild; // 右子节点指针
TreeNode(char c, int w) : ch(c), weight(w), lchild(nullptr), rchild(nullptr) {}
};
// 自定义比较函数用于优先队列
struct Compare {
bool operator()(TreeNode* a, TreeNode* b) {
return a->weight > b->weight;
}
};
// 获取哈夫曼编码
void getHuffmanCodes(TreeNode* root, string str, vector<string>& huffmanCode, map<char, int> freqMap) {
if (!root) return;
if (!root->lchild && !root->rchild) { // 如果到达叶子节点,则记录编码
huffmanCode[freqMap[root->ch]] = str;
return;
}
// 向左孩子移动时添加 '0'
getHuffmanCodes(root->lchild, str + "0", huffmanCode, freqMap);
// 向右孩子移动时添加 '1'
getHuffmanCodes(root->rchild, str + "1", huffmanCode, freqMap);
}
// 打印哈夫曼编码表
void printHuffmanCodes(vector<string>& huffmanCode, map<char, int> freqMap) {
for (auto it : freqMap) {
cout << "Character: " << it.first << ", Frequency: " << it.second
<< ", Huffman Code: " << huffmanCode[it.second] << endl;
}
}
int main() {
// 输入字符集和其频率
map<char, int> freqMap = {{'a', 5}, {'b', 9}, {'c', 12}, {'d', 13}, {'e', 16}, {'f', 45}};
priority_queue<TreeNode*, vector<TreeNode*>, Compare> pq;
// 创建叶节点并将它们加入优先队列
for (const auto& pair : freqMap) {
pq.push(new TreeNode(pair.first, pair.second));
}
// 不断取出两个最低频节点组合成新节点
while (pq.size() != 1) {
TreeNode* left = pq.top(); pq.pop();
TreeNode* right = pq.top(); pq.pop();
int sumWeight = left->weight + right->weight;
TreeNode* parent = new TreeNode('\0', sumWeight); // '\0' 表示非叶子节点
parent->lchild = left;
parent->rchild = right;
pq.push(parent);
}
// 最终剩下的即为根节点
TreeNode* root = pq.top();
// 准备存储哈夫曼编码的结果向量
vector<string> huffmanCode(freqMap.size(), "");
getHuffmanCodes(root, "", huffmanCode, freqMap);
// 输出最终结果
printHuffmanCodes(huffmanCode, freqMap);
return 0;
}
```
以上程序实现了完整的哈夫曼树构建过程,并能够打印出每个字符所对应的哈夫曼编码[^2]。
### 关于可能遇到的问题及解决方案
如果在运行过程中发现某些字符未被正确编码或者输出为空字符串,可能是由于以下原因造成的:
1. **输入数据异常**:确保传入的数据集中不存在重复键值对;如果有相同字符的不同频率情况,请提前处理好。
2. **内存泄漏风险**:动态分配了大量对象而没有释放可能导致资源浪费甚至溢出。可以考虑使用智能指针或手动清理所有已分配的对象实例。
3. **边界条件忽略**:当只有一个唯一字符存在时特殊对待,因为此时无需任何实际压缩操作即可表示原文件内容[^1]。
阅读全文
相关推荐

















