• C++实现基于哈夫曼树的数据压缩算法


    1. 需求分析

    现如今互联网无时无刻不在传输海量的数据,但这其中很多数据是冗余的,有非常多重复的字节(字符),如果设计一个转化表,将二进制数 01 代表一个 1 字节的字符,那么传输效率将大大提升。将二进制数替代本身字符有如下几点要求:

    • 因为需要解压,所以编码不能有异议性,也就是说任意字符对应的二进制数不能“包含其它字符对应的二进制数”
    • 需要尽可能地缩短编码的平均长度,可以让出现频率高的字符对应较短的字节,出现频率较低的字符对应较长的字节

    2. 总体设计

    根据以上需求,可以采用哈夫曼编码(Huffman Coding),哈夫曼编码是一种可变长编码,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字。

    考虑需要压缩的内容一般都非常长,不利于在命令行中输入及粘贴,所以考虑从文本文件(txt)中读取内容,压缩后输出在命令行中

    3. 详细设计

    数据结构:

    • 内容结构:
    typedef struct Contents
    {
        int size;  // 读入字串的大小
        char* pt;  // 读入的内容
        int* frequency;  // 存储每个字符出现的次数
        int** huffmanCode;  // 存储每个字符的哈夫曼编码
    } Contents;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 哈夫曼树结构:
    typedef struct HuffmanTreeNode
    {
        int weight;  // 结点的权重
        int value;  // 结点的值
        struct HuffmanTreeNode* LChild;  // 结点的左孩子
        struct HuffmanTreeNode* RChild;  // 结点的右孩子
    } Node,*PNode;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    函数:

    • 主模块:
    int main(int argc, char *argv[]);
    error()
    void error();
    
    • 1
    • 2
    • 3
    • 加密模块:
    void encode(char *argv[]);
    Contents* readFile(FILE *fp);
    void clear(Contents* content, PNode top);
    
    • 1
    • 2
    • 3
    • 文本分析模块:
    void frequency(Contents* content);
    PNode* intArray2PNodeArray(Contents* content);
    void sort(PNode* a,int i);
    
    • 1
    • 2
    • 3
    • 哈夫曼树模块:
    PNode createHuffmanTree(PNode * a);
    void InorderTraversal(PNode top);
    void PreorderTraversal(PNode top);
    void PostorderTraversal(PNode top);
    void printHuffmanTree(PNode top);
    void createHuffmanCoding(PNode top, Contents* content ,int* code , int n);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    另:源文件中有所有函数的详细解释(函数名、功能、调用的函数、被调用、输入、输出、返回值···),例如:

    在这里插入图片描述

    4. 系统测试与分析

    为了方便他人操作,我对程序做了两部优化:

    • 使用命令行参数来选择功能及选择文件

    在这里插入图片描述

    • 考虑到他人初次得到程序时不知道如何使用,我在设计程序时对不合法输入做了处理,使程序调用 error()函数来输出相关教程,非常简洁直观

    在这里插入图片描述

    • 在考虑输出格式时考虑了 windows 系统下换行符由“\t”“\n”两个字符组成,如果输入每个字符的表格的话会遇到输出格式的问题,所以一开始只输出 ASCII 码,但随后考虑到大量的 ASCII 码不利于阅读,权衡之下还是采用了字符输出。
    • 考虑到一般使用时需要直接得到哈夫曼编码,如果再保存到文件中会极大影响效率,因此将最后得到的哈夫曼编码直接显示在命令行中
    • 为应对各种错误情况,我对可能出现的错误(例如:不合法的输入、不存在的文件、文件被占用、内存分配失败···等情况都做了相对应的 error 处理)
      在这里插入图片描述

    在这里插入图片描述

    最后输出结果:

    在这里插入图片描述
    在这里插入图片描述

    (输出包括文本内容、字符出现的个数、生成的哈弗曼树、每个字符对应的哈夫曼编码、最后压缩生成的文本,非常详尽)

  • 相关阅读:
    DQL查询数据库
    信奥中的数学:约数
    海报素材要去哪里找?
    QTTabBar在重置Internet Explorer后失效
    大数据之Hive(三)
    java-net-php-python-ssm仓库管理系统计算机毕业设计程序
    路由规划——运输距离的估算
    python分享之读取xml文件
    leetcode 59. 螺旋矩阵 II
    金秋开学季,先进计算基础训练营开营了|猿代码科技
  • 原文地址:https://blog.csdn.net/sheziqiong/article/details/126011893