哈夫曼编码实验报告C++实现

该实验报告详细介绍了如何使用C++实现哈夫曼编码。首先,通过统计字符频率构建赫夫曼树,接着生成编码表并用其对源数据进行编码。此外,还涉及了解码过程,通过编码表查找对应字符。核心部分包括构造赫夫曼树的算法以及相关数据结构的设计。
摘要由CSDN通过智能技术生成

1、主要数据类型与变量

1.1使用到的头文件
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>    //map数据结构存储HT编码表
#include <queue>  //构建的节点的优先性
#include <string> //字符串方便输入输出
#include <iterator> //迭代器输出map展示
#include <fstream> //读写文件
1.2 使用类代替结构体,这里重载比较运算符,便于排序和构造优先队列。
class HTNode{
   
public:
    char ch; //字符
    int weight;//权重
    HTNode *left;//左孩子
    HTNode *right;//右孩子
    HTNode(int weight) : weight(weight) {
   }
    //重载比较运算符,便于排序,构造优先队列
    bool operator<(const HTNode &htnode) const{
   
        return weight > htnode.weight;
    }
    //两个构造函数
    HTNode(char ch, int weight, HTNode *left, HTNode *right) : ch(ch), weight(weight), left(left), right(right) {
   }
    HTNode(char ch, int weight) : ch(ch), weight(weight) {
   }
};
1.3函数结构说明
/**
 * 通过优先队列构建赫夫曼树
 * @param queue
 */
void CreateHuffmanTree(priority_queue<HTNode> &queue);
/**
 * 通过字符串统计字符的频率
 * @param s 需要统计的源数据
 * @return 返回一个优先队列,方便赫夫曼树筛选最小节点
 */
priority_queue<HTNode> count(string s);
/**
 * 展示每个字符对应的权重
 * @param q 优先字符队列
 */
void show(priority_queue<HTNode> q);
/**
 * 通过路径读取文件
 * @param path 需要读的文件路径
 * @return //以字符串类型返回文件中的数据
 */
string readFile(string path);
/**
 * 根据路径写入文件
 * @param path 文件路径
 * @param data 需要写入文件的内容(字符串类型)
 */
void writeFile(string path,string data);
void writeFile(string path,char data);//重载写文件函数,以char类型写入
static map<char,string> huffmanCode; //静态的全局变量map集合:key为字符,string为对应编码,用来作为编码表
/**
 * 获取编码表,此处配合静态的Map集合存入编码
 * @param root 赫夫曼树的根节点
 * @param code 路径编码,右为1,左为0
 * @param prefix 到该节点的路径,因为使用递归,所以要传入地址
 */
void getCodes(HTNode *root,string code,string &prefix);
/**
 * 打印编码表
 * @param codes 通过map集合配合迭代器输出每个字符对应的编码
 */
void printCode(map<char,string> codes);
/**
 * 通过编码表和文件读取出的数据来生成->编码数据
 * @param codetTable 编码表
 * @param data 数据源
 * @return 返回字符串展示编码数据
 */
string BecomeCode(map<char,string> codetTable,string data);
/**
 * 解码:通过编码表和编码后的数据
 * @param codetTable 编码表
 * @param CodeData 编码数据
 */
void deCode(map<char,string> codetTable,string CodeData);
2、算法或程序模块

2.1 程序流程解释:
①创建赫夫曼树:统计字符的频率由小到大放入优先队列,通过队列找出最小频率构建赫夫曼树。
②生成赫夫曼编码和赫夫曼编码后的数据:通过递归遍历赫夫曼树,通过Map集合创建编码表,再使用编码表和源数据生成编码后的数据。
③使用赫夫曼编码解码:通过查找编码后的数据配合编码表,通过查找方式输出对应的字符
核心函数解释
构造赫夫曼树:最小左右孩子的权重相加,生成父节点,然后父节点进队列

/**
 * 创建赫夫曼树
 * @param queue 构造的节点队列
 * @return 返回哈夫曼树的根节点
 */
void CreateHuffmanTree(priority_queue<HTNode> &queue){
   
    while (queue.size()>1){
   
        HTNode *left = new HTNode(queue.top()); queue.pop(); //队列弹出左右孩子
        HTNode *right = new HTNode(queue.top()); queue.pop();
        HTNode parent('R',left->weight + right->weight,left,right);//通过最小的两个节点权重相加构造父节点
        queue.push(parent);//父节点进队列
    }
}

统计每个字符出现的频率:字符范围是ASCALL:0-128
priority_queue<HTNode> count(string s){
   
    int a[128
  • 1
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值