当前位置: 首页 > news >正文

数据结构作业-6.2哈夫曼树

#include stdio.h #include fstream//文件读写 #include string.h//字符串操作strcpy,strlen) #define MaxSize 1024//读取文件最大长度 #define OK 1 #define ERROR 0 typedef int Status;//用 Status代表函数返回状态成功/失败 typedef struct wordcnt{ char ch;//统计字符 int cnt 0;//统计这个字符出现了多少次 }Count; typedef struct NumCount{ //封装上面所有的字符和长度 Count count[MaxSize];//存所有的字符和长度 int length 0;//实际有多少种不同字符 }NumCount; typrdef struct HTree{//哈夫曼树结构 int data; int weight;//权重出现次数 int parent,lchild,rchile;//下标 }HTNode,*HuffmanTree; typedef struct HCode{//编码结构 char data;//对应字符 char* str;//编码字符串 }*HuffmanCode; //函数声明 Status ReadData(char *source); // 读入文件 Status WordCount(char *data,NumCount *paraCnt); // 统计次数 Status Show(NumCount *paraCnt); // 展示次数 Status CreateHuffmanTree(HuffmanTree HT,int length,NumCount cntarray); // 创建哈夫曼树 Status select(HuffmanTree HT,int top,int *s1,int *s2); // 选择权重最小的两个节点 Status CreateHuffmanCode(HuffmanTree HT,HuffmanCode HC,int length); // 创建哈夫曼编码 Status Encode(char *data,HuffmanCode HC,int length); // 将读入的文件编码写到txt文件 Status Decode(HuffmanTree HT,int length); //读入编码文件解码 //主函数 int main() { char data[MaxSize];//存读入的文本 NumCount Cntarray;//存字符统计结果 ReadData(data);// 1.读 in.txt WordCount(data,Cntarray); // 2.统计字符次数 HuffmanTree tree; CreateHuffmanTree(tree,Cntarray.length,Cntarray); //3.建树 HuffmanCode code; CreateHuffmanCode(tree,code,Cntarray.length);//4.生成编码 Encode(data,code,Cntarray.length); //5.编码写入code.txt Decode(tree,Cntarray.length);//6.解码写入out.txt cout完成查看文件即可endl; return 0; } Status ReadData(char *source){//读取文本文件 ifstream infile;// 输入文件流 infile.open(in.txt);//打开in.txt coutReading...endl; infile.getline(source,MaxSize); //读取一行到source数组 coutsourceendl; infile.close(); return OK; } Status WordCount(char *data,NumCount *paraCnt){//统计每个字符出现多少次 int len strlen(data); // 文本总长度 for(int i0;ilen;i){ int flag0; // 看看这个字符之前有没有统计过 for(int j0;jparaCnt-length;j){ if(paraCnt-count[j].ch data[i]){ paraCnt-count[j].cnt; // 次数1 flag1; break; } } if(!flag){ // 没统计过新增 paraCnt-count[paraCnt-length].ch data[i]; paraCnt-count[paraCnt-length].cnt; paraCnt-length; } } return OK; } Status CreateHuffmanTree(HuffmanTree HT,int length,NumCount cntarray){//构建哈夫曼树 int m length*2-1; //总节点数 2*叶子数-1//两个孩子构成一个新节点 HT new HTNode[m1]; //开辟数组空间 // 1. 初始化所有节点 for(int i1;im;i){ HT[i].parent0; HT[i].lchild0; HT[i].rchild0; } // 2. 填入叶子节点字符和权重 for(int i1;ilength;i){ HT[i].data cntarray.count[i-1].ch; HT[i].weight cntarray.count[i-1].cnt; } // 3. 循环合并最小两个节点 for(int ilength1;im;i){ int s1,s2; select(HT,i-1,s1,s2); // 选最小两个 HT[s1].parent i; HT[s2].parent i; HT[i].lchild s1; HT[i].rchild s2; HT[i].weight HT[s1].weight HT[s2].weight;//得到新节点 } return OK; } Status select(HuffmanTree HT,int top,int *s1,int *s2){//选出权重最小的两个节点 int min INT_MAX; // 找最小 for(int i1;itop;i){ if(HT[i].weight min HT[i].parent 0){ min HT[i].weight; *s1 i; } } // 找次小 min INT_MAX; for(int i1;itop;i){ if(HT[i].weight min i!*s1 HT[i].parent0){ min HT[i].weight; *s2 i; } } return OK; } Status CreateHuffmanCode(HuffmanTree HT,HuffmanCode HC,int length){//生成编码 HC new HCode[length1]; char *cd new char[length]; // 存储编码的临时空间 cd[length-1] \0; // 方便之后调用strcpy函数 int c,f,start; for(int i 1;i length;i) { start length-1; // start表示编码在临时空间内的起始下标由于是从叶子节点回溯所以是从最后开始 c i; f HT[c].parent; while(f ! 0) { --start; //由于是回溯所以从临时空间的最后往回计 if(HT[f].lchild c) cd[start] 0; else cd[start] 1; c f; f HT[c].parent; } HC[i].str new char[length-start]; // 最后实际使用的编码空间大小是length-start HC[i].data HT[i].data; strcpy(HC[i].str,cd[start]); // 从实际起始地址开始拷贝到编码结构中 } delete cd; } Status Encode(char *data,HuffmanCode HC,int length) { ofstream outfile; outfile.open(code.txt); for(int i 0;i strlen(data);i) // 依次读入数据查找对应的编码写入编码文件 { for(int j 1;j length;j) { if(data[i] HC[j].data) { outfileHC[j].str; } } } outfile.close(); coutthe code txt has been writtenendl; coutendl; return OK; } Status Decode(HuffmanTree HT,int length) { char codetxt[MaxSize*length]; ifstream infile; infile.open(code.txt); infile.getline(codetxt,MaxSize*length); infile.close(); ofstream outfile; outfile.open(out.txt); int root 2*length-1; // 从根节点开始遍历 for(int i 0;i strlen(codetxt);i) { if(codetxt[i] 0) root HT[root].lchild; //为0表示向左遍历 else if(codetxt[i] 1) root HT[root].rchild; //为1表示向右遍历 if(HT[root].lchild 0 HT[root].rchild 0) // 如果已经是叶子节点输出到输出文件中然后重新回到根节点 { outfileHT[root].data; root 2*length-1; } } outfile.close(); coutthe output txt has been writtenendl; coutendl; return OK; }
http://www.zskr.cn/news/1409422.html

相关文章:

  • 【开源软件移植】NitroShare 适配鸿蒙 PC 全流程实战 — Qt-OHOS × 手把手移植教程
  • 分数阶微积分导向的离散制造检测数据融合技术【附算法】
  • 程序员3年卡18k?收藏这份AI转型指南,弯道超车迎高薪!
  • 手把手教你用OSX-KVM项目搞定macOS安装镜像(从dmg到iso的完整转换流程)
  • 微电磁力称重传感器温度补偿算法:从硬件局限到软件动态区间补偿
  • 告别龟速下载:用bypy+aria2在Linux服务器上满速搬运百度网盘大文件
  • CUSUM控制图在Python金融风控中的应用:如何用它监测交易策略的失效?
  • 别再重启虚拟机了!详解Linux SCSI总线扫描,让新硬盘秒识别
  • DSM在零延迟仿真中的异常行为分析与解决方案
  • 基于OpenCL的FPGA信号处理:低延迟流水线设计与工程实践
  • 哈夫曼数 。
  • 脑卒中(中风)研究现状、研究思路详细解析
  • 告别零散脚本:在MeterSphere里用‘场景’优雅管理你的模块CRUD接口测试
  • 26个高质量阅读APP书源:新手必备的一键导入完整指南
  • 2026年 宝钢镀锌HC850/1180DHD+Z吉帕钢测评:超强车身用钢的行业标杆与选购推荐 - 品牌企业推荐师(官方)
  • ArcGIS坐标转点常见三大坑:Excel格式、坐标系选错、点顺序乱,附避坑实操
  • Python爬虫遇到InsecureRequestWarning?别慌,这3种方法帮你搞定SSL证书验证警告
  • 腾讯云Windows Server上,如何一劳永逸地解决Defender SmartScreen弹窗?附三种方案对比
  • 保姆级教程:用CAT_pack和IMG/VR4数据库搞定宏基因组contig物种分类(附蛋白ID与TaxID映射避坑指南)
  • 别再只盯着准确率了!手把手教你用Python计算语义分割的MIoU(附完整代码)
  • 告别命令行恐惧:Windows 10/11 下 SRA Toolkit 安装与配置保姆级图文教程
  • 生成式AI政策沙盒实测报告(北京/上海/深圳首批入盒企业独家访谈):政策红利如何转化为产品上线加速器?
  • 2026年哈尔滨消防设施操作员培训机构推荐榜:消控证/消防中控/监控操作/维保操作/中级消防证/消防考证/消防实操/维保证/监控证/消防上岗证精选品牌与实战口碑解析 - 品牌企业推荐师(官方)
  • 为什么你的ChatGPT健身计划总失败?运动生理学博士揭穿5大AI认知盲区,附可立即复用的Prompt黄金模板
  • 电力系统实时仿真技术:从硬件在环到主流平台实践
  • 纹理压缩选型指南:ASTC、ETC、BCn到底怎么选?结合Unity/Unreal引擎实战解析
  • Jellyfin MetaTube插件:构建现代化媒体元数据管理系统的完整解决方案
  • RIMMS:异构计算内存管理的革命性突破
  • 【绝密工作流】高管私藏的ChatGPT目标校准术:融合PDCA×GTD×神经反馈原理,实测目标达成率提升63.7%
  • 【限时解密】头部咨询公司内部禁用的ChatGPT决策辅助工具黑名单:12个触发监管红线的操作模式