【C语言】C语言 哈夫曼编码传输(源码+数据文件)【独一无二】

请添加图片描述


👉博__主👈:米码收割机
👉技__能👈:C++/Python语言
👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。


C语言 哈夫曼编码传输(源码+数据文件)【独一无二】


目录

  • C语言 哈夫曼编码传输(源码+数据文件)【独一无二】
  • 一、设计要求
  • 二、设计思路
    • 2. 核心数据结构与辅助函数
      • 2.1 数据结构定义
      • 2.2 最小堆辅助函数
    • 3. 哈夫曼树的构建与编码生成
      • 3.1 构建哈夫曼树
      • 3.2 生成哈夫曼编码表
    • 4. 文件编码、解码与验证
      • 4.1 编码文件
      • 4.2 解码文件
      • 4.3 文件一致性对比
    • 5. 主函数及整体工作流程


一、设计要求

问题4:某系统在通信联络中需要传送一个英文文件,该文件包含26个英文字母和空格等字符。请自行准备一个文本文件,要求这个文件中总符号数不少于10000个。要求运用哈夫曼编码方法,对该文本文件进行编码和解码,并校验解码后的文本正确性。请编写具体的计算机程序

在这里插入图片描述


二、设计思路

在这里插入图片描述

整个程序可以分为以下几个主要部分:

  1. 文件操作与预处理

    • 获取文件大小(getFileSize())。
    • 统计输入文件中每个字符的出现频率,为构建哈夫曼树做准备。
  2. 核心数据结构与辅助工具

    • 定义哈夫曼树节点(HuffmanTreeNode)和最小堆(MinHeap)的数据结构。
    • 实现最小堆的基本操作:插入、交换、向下调整(minHeapify())与提取最小节点(extractMin())。
  3. 哈夫曼树构建与编码表生成

    • 根据字符频率构建哈夫曼树,采用贪心策略不断合并频率最低的两个节点。
    • 遍历哈夫曼树生成每个字符的二进制编码(buildCodes()),并存入全局编码表 huffmanCode 中。
  4. 文件编码与解码

    • 通过编码表对原始文件进行编码(encodeFile()),将字符转换成由 0 和 1 组成的字符串保存到输出文件中。
    • 利用构建好的哈夫曼树对编码后的文件进行解码(decodeFile()),还原出原始文本信息。
  5. 验证与性能统计

    • 对比原始文件和解码后的文件(compareFiles())确保解码准确性。
    • 计算文件压缩率,展示压缩效果。

2. 核心数据结构与辅助函数

2.1 数据结构定义

程序中定义了两个核心数据结构,在哈夫曼编码中起到重要作用:

  • 哈夫曼树节点(HuffmanTreeNode)

    每个节点存储一个字符及其出现频率,同时包含左右孩子指针。例如:

    typedef struct HuffmanTreeNode {
        unsigned char ch;   // 字符
        unsigned freq;      // 字符频率
        struct HuffmanTreeNode *left, *right;
    } HuffmanTreeNode;
    
  • 最小堆(MinHeap)

    最小堆用于快速找到频率最小的节点,在构建哈夫曼树过程中非常关键:

    typedef struct MinHeap {
        int size;
        int capacity;
        HuffmanTreeNode** array;
    } MinHeap;
    

2.2 最小堆辅助函数

程序实现了常用的最小堆操作,包括节点交换、向下调整(minHeapify())、插入节点(insertMinHeap())和提取最小节点(extractMin())。
例如,向下调整函数保证了堆的性质:

void minHeapify(MinHeap* minHeap, int idx) {
    int smallest = idx;
    int left = 2 * idx + 1;
     // 代码略....
    if (right < minHeap->size &&
        minHeap->array[right]->freq < minHeap->array[smallest]->freq) {
        smallest = right;
    }
    if (smallest != idx) {
        swapNode(&minHeap->array[smallest], &minHeap->array[idx]);
        minHeapify(minHeap, smallest);
    }
}

在这里插入图片描述


3. 哈夫曼树的构建与编码生成

3.1 构建哈夫曼树

函数 buildHuffmanTree() 根据统计好的字符频率构建哈夫曼树,其基本流程如下:

  1. 统计有效字符数量
    遍历频率表,统计每个出现过的字符个数以确定最小堆的容量。

  2. 构建最小堆并插入所有字符节点
    为每个出现的字符创建一个节点,并插入到最小堆中。

  3. 合并最小节点
    循环执行以下操作:

    • 提取两个最小频率的节点。
    • 创建一个新节点,其频率为两节点频率之和,新节点左右指针指向这两个节点。
    • 将新节点重新插入堆中,直到堆中只剩下一个节点,该节点即为哈夫曼树的根。

部分代码示例如下:

while (minHeap->size > 1) {
    HuffmanTreeNode* left = extractMin(minHeap);
    HuffmanTreeNode* right = extractMin(minHeap);
    HuffmanTreeNode* top = createNode('\0', left->freq + right->freq);
    top->left = left;
    top->right = right;
    insertMinHeap(minHeap, top);
}

3.2 生成哈夫曼编码表

利用已经构建好的哈夫曼树,通过递归方式生成每个字符的编码:

  • 当递归向左(代表二进制“0”)或右(代表二进制“1”)不断累积编码,直到遇到叶子节点;
  • 到达叶子节点后,将生成的二进制字符串保存到全局编码表 huffmanCode 中。

函数示例:

void buildCodes(HuffmanTreeNode* root, char* code, int length) {
    if (!root) return;
     // 代码略....
    code[length] = '0';
    buildCodes(root->left, code, length + 1);
    code[length] = '1';
    buildCodes(root->right, code, length + 1);
}

在这里插入图片描述


4. 文件编码、解码与验证

4.1 编码文件

函数 encodeFile() 打开原始文件,并对每个字符用对应的哈夫曼编码替换后写入到编码文件中。
关键代码:

while ((ch = fgetc(fin)) != EOF) {
    fputs(huffmanCode[ch], fout);
}

4.2 解码文件

函数 decodeFile() 根据编码文件中的 0/1 流,利用哈夫曼树反向遍历解码还原每个字符,直到完整还原出原始文本:

HuffmanTreeNode* curr = root;
while ((bit = fgetc(fin)) != EOF) {
    if (bit == '0')
        curr = curr->left;
    else if (bit == '1')
        curr = curr->right;
    // 到达叶子节点,输出字符
    if (!curr->left && !curr->right) {
        fputc(curr->ch, fout);
        curr = root;
    }
}

4.3 文件一致性对比

函数 compareFiles() 将原始文件和解码后的文件进行字节级对比,确保解码过程没有任何错误:

do {
    c1 = fgetc(f1);
    c2 = fgetc(f2);
    if (c1 != c2) { /* 不同 */
        fclose(f1);
        fclose(f2);
        return 0;
    }
} while (c1 != EOF && c2 != EOF);

在这里插入图片描述


5. 主函数及整体工作流程

主函数 main() 整合了上述所有步骤,其主要流程如下:

  1. 预处理与频率统计

    • 判断原始文件是否存在,读取文件大小。
    • 遍历文件,统计每个字符的出现频率,填充频率表 freqTable
  2. 构建哈夫曼树与生成编码表

    • 调用 buildHuffmanTree() 构建哈夫曼树;
    • 通过 buildCodes() 生成用于编码的哈夫曼编码表。
  3. 执行编码与解码

    • 使用 encodeFile() 对原始文件进行编码;
    • decodeFile() 将编码后文件解码为还原文件。
  4. 结果验证与性能评估

    • 调用 compareFiles() 检查解码文件与原文件是否一致;
    • 计算压缩率,并打印原始大小、压缩后大小及压缩率。

主函数示例代码:

int main() {
    const char* inputFile    = "input.txt";    // 原始文件
    const char* encodedFile  = "encoded.txt";  // 编码结果(0/1串)
    const char* decodedFile  = "decoded.txt";  // 解码结果

    // 1) 读取原文件大小
        // 代码略....

    // 3) 构建哈夫曼树
    HuffmanTreeNode* root = buildHuffmanTree(freqTable);

    // 代码略....

    printf("原文件大小:%ld 字节\n", originalSize);
    printf("压缩后文件大小:%ld 字节\n", compressedSize);
    printf("压缩率:%.2f%%\n", ratio);
    printf("解压后文本与原文本相同:%s\n", isSame ? "True" : "False");

    // 释放哈夫曼树
    freeHuffmanTree(root);

    return 0;
}

运行结果:
在这里插入图片描述

---

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/972568.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用命令模式设计一个JSBridge用于JavaScript与Android交互通信

用命令模式设计一个JSBridge用于JavaScript与Android交互通信 在开发APP的过程中&#xff0c;通常会遇到Android需要与H5页面互相传递数据的情况&#xff0c;而Android与H5交互的容器就是WebView。 因此要想设计一个高可用的 J S B r i d g e JSBridge JSBridge&#xff0c;不…

3月营销日历:开启春日盛宴,绽放生活魅力

关键营销节点∶惊蛰、女生节、妇女节、 植树节、315消费者权益日、春分 营销关键词 养生、女生魅力、感恩女性、环保、品质 01.重点关注品类 春季服饰&#xff1a;如轻薄外套、春装等&#xff0c;适合惊蛰后的市场需求&#xff1b; 美妆护肤&#xff1a;妇女节期间&#xf…

GPT-SoVITS更新V3 win整合包

GPT-SoVITS 是由社区开发者联合打造的开源语音生成框架&#xff0c;其创新性地融合了GPT语言模型与SoVITS&#xff08;Singing Voice Inference and Timbre Synthesis&#xff09;语音合成技术&#xff0c;实现了仅需5秒语音样本即可生成高保真目标音色的突破。该项目凭借其开箱…

AI芯片:科技变革的核心驱动力

近年来&#xff0c;人工智能&#xff08;AI&#xff09;的飞速发展对众多行业产生了深远影响&#xff0c;芯片领域也不例外。AI在芯片设计、制造及应用等方面带来了革新性的改变&#xff0c;成为推动芯片行业发展的关键力量。 AI助力芯片设计效率飞升 传统芯片设计极为复杂&am…

【phpstudy】关于实现两个不同版本的mysql并存。

1.首先是先安装好两个版本的mysql mysql5.7用默认的就行 2.更改mysql8.0的配置&#xff0c;如图 3.找到mysql8.0的路径&#xff0c;看着个里面就可以知道了 4.进入后&#xff0c;可以把data里面的数据情况&#xff0c;就是把data文件夹里的东西删除&#xff08;我是先备份好了一…

Coze扣子新功能详解

今晚(2025-01-24)扣子再次进行更新 主要更新内容&#xff1a; 搭建小程序和 H5 用户界面时&#xff0c;支持使用音频组件播放音频内容 数据库操作体验提升 界面优化&#xff1a;对数据库详情界面进行了重新设计&#xff0c;并将工作流运行数据库的测试数据位置从原工作流底…

Pytorch深度学习教程_3_初识pytorch

欢迎来到《PyTorch深度学习教程》系列的第三篇&#xff01;在前面的两篇中&#xff0c;我们已经介绍了Python及numpy的基本使用。今天&#xff0c;我们将深入探索PyTorch的核心功能&#xff0c;帮助你更好地理解和使用这个强大的深度学习框架。 欢迎订阅专栏&#xff1a; 深度…

第4章 信息系统架构(二)

4.2 系统架构 信息系统架构是一种体系结构&#xff0c;它反映了一个组织信息系统的各个组成部分之间的关系&#xff0c;以及信息系统与相关业务、信息系统与相关技术之间的关系。 4.2.1 架构定义 对于大规模的复杂系统来说&#xff0c;对总体的系统结构设计比起对计算算法和…

剑指 Offer II 024. 反转链表

comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20024.%20%E5%8F%8D%E8%BD%AC%E9%93%BE%E8%A1%A8/README.md 剑指 Offer II 024. 反转链表 题目描述 给定单链表的头节点 head &#xff0c;请反转链表&#xff…

Python----数据结构(单链表:节点,是否为空,长度,遍历,添加,删除,查找)

一、链表 链表是一种线性数据结构&#xff0c;由一系列按特定顺序排列的节点组成&#xff0c;这些节点通过指针相互连接。每个节点包含两部分&#xff1a;元素和指向下一个节点的指针。其中&#xff0c;最简单的形式是单向链表&#xff0c;每个节点含有一个信息域和一个指针域&…

Java开发实习面试笔试题(含答案)

在广州一家中大公司面试&#xff08;BOSS标注是1000-9999人&#xff0c;薪资2-3k&#xff09;&#xff0c;招聘上写着Java开发&#xff0c;基本没有标注前端要求&#xff0c;但是到场知道是前后端分离人不分离。开始先让你做笔试&#xff08;12道问答4道SQL题&#xff09;&…

Docker:3、在VSCode上安装并运行python程序或JavaScript程序

1.VSCode上安装并运行python程序&#xff1a; 1.1.安装Docker插件 1.2.新建自动化脚本DockerFile FROM python:3.-slim-buster WORKDIR /app COPY .. RUN pip3 install -r requirements.txt CMD ["python3", "app.py"]COPY <本地路径><目标…

MOS管炸了,PWM“死区”时间得了解一下

从字面上来看“死区”的意思就是&#xff1a;如果处于这个区&#xff0c;那就会出现“损坏”的现象&#xff0c;直白点&#xff0c;就是“禁区”&#xff01; 实际应用中&#xff0c;比如大功率设备的电机&#xff0c;还有变频器等驱动电路&#xff0c;多部分都是采用MOS管和IG…

idea-代码补全快捷键

文章目录 前言idea-代码补全快捷键1. 基本补全2. 类型匹配补全3. 后缀补全4. 代码补全 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;…

保姆级教程:利用Ollama与Open-WebUI本地部署 DeedSeek-R1大模型

1. 安装Ollama 根据自己的系统下载Ollama&#xff0c;我的是Linux&#xff0c;所以我使用如下命令进行下载安装&#xff1a; curl -fsSL https://ollama.com/install.sh | sh2. 安装Open-WebUI 使用 Docker 的方式部署 open-webui &#xff0c;使用gpu的话按照如下命令进行 …

win10 系统 自定义Ollama安装路径 及模型下载位置

win10 系统 自定义Ollama安装路径 及模型下载位置 由于Ollama的exe安装软件双击安装的时候默认是在C盘&#xff0c;以及后续的模型数据下载也在C盘&#xff0c;导致会占用C盘空间&#xff0c;所以这里单独写了一个自定义安装Ollama安装目录的教程。 Ollama官网地址&#xff1…

以教代学——费曼学习法

本文是思维导图&#xff0c;算是费曼学习法精髓我的个人总结&#xff0c;如果条件允许的话可以去看看费曼自传性质的书&#xff0c;书名见文末。 《别闹了&#xff0c;费曼先生》&#xff1a;英文书名为《Surely Youre Joking, Mr. Feynman!》&#xff0c;这是一本自传性质的书…

JWT 令牌

目录 一、JWT 1、什么是JWT 2、JWT的组成 3、JJWT签发与验证token 1、创建token 2、解析token 3、设置过期时间 4、自定义claims 前言&#xff1a; 在现代Web应用和微服务架构中&#xff0c;用户身份验证和信息安全传输是核心问题。JSON Web Token&#xff08;J…

工控网络安全介绍 工控网络安全知识题目

31.PDR模型与访问控制的主要区别(A) A、PDR把对象看作一个整体 B、PDR作为系统保护的第一道防线 C、PDR采用定性评估与定量评估相结合 D、PDR的关键因素是人 32.信息安全中PDR模型的关键因素是(A) A、人 B、技术 C、模型 D、客体 33.计算机网络最早出现在哪个年代(B) A、20世…

快速定位并优化CPU 与 JVM 内存性能瓶颈

1. CPU 性能优化实战 CPU&#xff08;Central Processing Unit&#xff09;是计算机系统的运算和控制核心&#xff0c;是信息处理、程序运行的最终执行单元&#xff0c;相当于系统的“大脑”。当 CPU 过于繁忙&#xff0c;就像“人脑”并发处理过多的事情&#xff0c;会降低做…