C/C++ 哈夫曼树的构造、编码以及译码

题目》:假设用于通信的电文由字符集{a,b,c,d,e,f,g,h}中的字母构成,这8个字母在电文中出现的 频率分别为:{0.19, 0.21, 0.02, 0.03, 0.06, 0.07, 0.1, 0.32}.
要求:画出哈夫曼树。


我从课本上面摘抄了一个题目,题目大概是上面这样的,我们这里只是详细的说明一下哈弗曼树要怎么构建。借用一下这个题目。

哈夫曼树的构造

分析:我们这里直接将小数整数化,容易看出大小来。

①8个结点的权值大小如下:
这里写图片描述
②从19,21,2,3,6,7,10,32中选择两个权小结点。选中2,3。同时算出这两个结点的和5。
这里写图片描述
③从19,21,6,7,10,32,5中选出两个权小结点。选中5,6。同时计算出它们的和11。
这里写图片描述
④从19,21,7,10,32,11中选出两个权小结点。选中7,10。同时计算出它们的和17。
注:这时选出的两个数字都不是原来的二叉树里面的结点,所以要另外开一棵二叉树。
这里写图片描述
⑤从19,21,32,11,17中选出两个权小结点。选中11,17。同时计算出它们的和28。
这里写图片描述
⑥从19,21,32,28中选出两个权小结点。选中19,21。同时计算出它们的和40。 另起一颗二叉树。
这里写图片描述
⑦从32,28, 40中选出两个权小结点。选中28,32。同时计算出它们的和60。
这里写图片描述
⑧从 40, 60中选出两个权小结点。选中40,60。同时计算出它们的和100。 好了,此时哈夫曼树已经构建好了。
这里写图片描述

ps:上次做作业的时候,我构造哈弗曼树就是一直从剩下的结点里面找权值最小的,然后添加上去,而没有考虑构造出来的”和”权值的大小问题。导致哈夫曼树构造错误!

哈夫曼编码及译码的实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//树结点定义
typedef  struct 
{
    int weight;
    int parent;
    int lchild;
    int rchild;
}HTNode,*HuffmanTree;

static char N[100];//用于保存正文

//哈弗曼编码,char型二级指针
typedef char **HuffmanCode;

//封装最小权结点和次小权结点
typedef  struct 
{
    
  • 116
    点赞
  • 484
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
哈夫曼树是一种用于数据压缩的树形结构,可以通过构建哈夫曼树来得到哈夫曼编码。下面是用C++实现哈夫曼树和哈夫曼编码的示例代码: ```c++ #include <iostream> #include <queue> #include <vector> #include <string> #include <unordered_map> using namespace std; // 哈夫曼树节点 struct HuffmanNode { char ch; // 字符 int freq; // 出现频率 HuffmanNode *left, *right; // 左右子节点 HuffmanNode(char c, int f) : ch(c), freq(f), left(nullptr), right(nullptr) {} }; // 用于比较哈夫曼树节点的函数对象 class HuffmanNodeCompare { public: bool operator()(HuffmanNode* a, HuffmanNode* b) { return a->freq > b->freq; // 以出现频率为优先级 } }; // 构建哈夫曼树 HuffmanNode* buildHuffmanTree(string str) { unordered_map<char, int> freqMap; // 统计各字符出现频率 for (char c : str) { freqMap[c]++; } priority_queue<HuffmanNode*, vector<HuffmanNode*>, HuffmanNodeCompare> pq; // 将字符及其出现频率构建成哈夫曼树节点,并加入优先队列 for (auto it = freqMap.begin(); it != freqMap.end(); it++) { HuffmanNode* node = new HuffmanNode(it->first, it->second); pq.push(node); } // 逐步合并哈夫曼树节点,直到只剩下一个节点,即根节点 while (pq.size() > 1) { HuffmanNode* left = pq.top(); pq.pop(); HuffmanNode* right = pq.top(); pq.pop(); HuffmanNode* parent = new HuffmanNode('$', left->freq + right->freq); parent->left = left; parent->right = right; pq.push(parent); } return pq.top(); } // 递归遍历哈夫曼树,得到字符的哈夫曼编码 void getHuffmanCode(HuffmanNode* node, string code, unordered_map<char, string>& codeMap) { if (!node) { return; } if (node->ch != '$') { codeMap[node->ch] = code; } getHuffmanCode(node->left, code + "0", codeMap); getHuffmanCode(node->right, code + "1", codeMap); } int main() { string str = "hello world"; HuffmanNode* root = buildHuffmanTree(str); unordered_map<char, string> codeMap; getHuffmanCode(root, "", codeMap); cout << "Huffman codes:" << endl; for (auto it : codeMap) { cout << it.first << ": " << it.second << endl; } return 0; } ``` 代码中,先统计字符串中各字符的出现频率,然后将它们构建成哈夫曼树节点,并加入优先队列。接着,逐步合并哈夫曼树节点,直到只剩下一个节点,即根节点。最后,递归遍历哈夫曼树,得到各字符的哈夫曼编码

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值