哈夫曼编/译码器
任务:建立最优二叉树函数。
要求:可以建立函数输入二叉树,并输出其哈夫曼树。
在上交资料中请写明:存储结构、基本算法(可以使用程序流程图)、输入输出、源程序、测试数据和结果、算法的时间复杂度、另外可以提出算法的改进方法;
利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼码的编/译码系统。
一个完整的系统应具有以下功能:
(1)I:初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。
(2)E:编码(Encoding)。利用已建好的哈夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
(3)D:译码(Decoding)。利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。
(4)P:印代码文件(Print)。将文件CodeFile以紧凑格式显示在终端上,每行50个代码。同时将此字符形式的编码文件写入文件CodePrin中。
(5)T:印哈夫曼树(Tree printing)。将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。

huffman树的数据结构定义如下:

typedef struct
{int weight;int lchild,rchild,parent;
} HTNode,*HuffmanTree;

(一)哈夫曼树的建立
1.从所给数据中选择两个最小的值

void Select(HuffmanTree HT,int n,int &s1,int &s2)
{int i=1;while(HT[i].parent!=0&&i<=n)//找到一个还没连接的,即parent=0;i++;if(i==n+1)return ;s1=i;i++;while(HT[i].parent!=0&&i<=n)//同上i++;if(i==n+1)return ;s2=i;i++;if(HT[s1].weight>HT[s2].weight)//让s1比s2小swap(s1,s2);for(; i<=n; i++){if(HT[i].parent==0){if(HT[i].weight<HT[s1].weight)s2=s1,s1=i;else if(HT[i].weight<HT[s2].weight)s2=i;}}return ;
}

2.根据输入的字符和权值建立哈夫曼树

void CreatHuffmanTree(HuffmanTree &HT,int n)
{if(n<=1)return ;int m=2*n-1;//树共有2n-1个节点HT=(HuffmanTree)malloc(sizeof(HTNode)*(m+1));//从1开始多申请一个for(int i=1; i<=m; i++)//初始化{HT[i].lchild=0;HT[i].parent=0;HT[i].rchild=0;HT[i].weight=0;}for(int i=1; i<=n; i++)cin>>HT[i].weight;int s1,s2;for(int i=n+1; i<=m; i++)//后n-1个节点的创建{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 ;
}

(二)根据哈夫曼树对字符进行编码

void CreatHuffmanCode(HuffmanTree &HT,char ** &HC,int n)
{char *col;HC=(char **)malloc(sizeof(char *)*(n+1));col=(char *)malloc(sizeof(char)*n);//存储每个编码的临时空间col[n-1]='\0';//为什么是n-1,n个节点创建的哈夫曼树高为n-1//路径条数为n-2,最长的只有n-2个数字。for(int i=1; i<=n; i++){int str=n-1;int p=i,f=i;while(HT[f].parent!=0)//从叶向上寻找{f=HT[f].parent;if(HT[f].lchild==p)col[--str]='0';else if(HT[f].rchild==p)col[--str]='1';p=f;}HC[i]=(char *)malloc(sizeof(char)*(n-str));    //为第i个字符编码分配空间strcpy(HC[i],&col[str]);//复制到编码中}free(col);return ;
}

(三)翻译文件中的码

void TransCode(HuffmanTree HT,char b[],char a[],char c[],int n)
{//b数组是要翻译的二进制编码//a数组是叶子对应的字符//c数组存储翻译得到的内容FILE *fw;int q=2*n-1;   //初始化为根结点的下标int k=0;int len=strlen(b);if((fw=fopen("textfile.txt","w"))==NULL)cout<<"Open file error!"<<endl;for(int i=0; i<len; i++){if(b[i]=='0')q=HT[q].lchild;else if(b[i]=='1')q=HT[q].rchild;if(HT[q].lchild==0&&HT[q].rchild==0)//叶子节点,此时可译{c[k++]=a[q];fputc(a[q],fw);q=2*n-1;}c[k]='\0';}return ;
}

(四)对文件中的字符进行编码

void Coding(HuffmanTree &HT,char ** &HC,int n,char a[])
{FILE *fp,*fw;char c;int k;if((fp=fopen("tobetran.txt","r"))==NULL)cout<<"Open file error!"<<endl;if((fw=fopen("codefile.txt","w"))==NULL)cout<<"Open file error!"<<endl;fscanf(fp,"%c",&c);//从文件中读取一个字符while(!feof(fp)){for(int i=1; i<=n; i++)if(a[i]==c)//找到对应的编码{k=i;break;}for(int i=0; HC[k][i]!='\0'; i++)//输出该字符编码fputc(HC[k][i],fw);fscanf(fp,"%c",&c);//继续下一个}fclose(fp);fclose(fw);return ;
}

(五)打印编码

void printf_code()
{FILE *fp,*fw;char temp;if((fp=fopen("codefile.txt","r"))==NULL)cout<<"error"<<endl;if((fw=fopen("codeprin.txt","w"))==NULL)cout<<"error"<<endl;cout<<"codefile.txt:"<<endl;fscanf(fp,"%c",&temp);for(int i=1;!feof(fp);i++){printf("%c",temp);if(i%50==0)//50个一换行cout<<endl;fputc(temp,fw);//再写到codeprint文件中fscanf(fp,"%c",&temp);}cout<<endl;cout<<"编码已存入文件codeprin.txt"<<endl;fclose(fp);fclose(fw);
}

(六)打印哈夫曼树
(1)生成空格

void co_tree(unsigned char T[100][100],int s,int *m,int j,HuffmanTree HT)
{int k,l;l=++(*m);for(k=0;k<s;k++)//深度越深,前面空格越多T[l][k]=' ';T[l][k]=HT[j].weight;if(HT[j].lchild)co_tree(T,s+1,m,HT[j].lchild,HT);if(HT[j].rchild)co_tree(T,s+1,m,HT[j].rchild,HT);T[l][++k]='\0';return ;
}

(2)打印哈夫曼树

void printf_tree(int num,HuffmanTree HT)
{unsigned char T[100][100];FILE *fp;int m=0;co_tree(T,0,&m,2*num-1,HT);if((fp=fopen("treeprin.txt","w"))==NULL)cout<<"Open file error!"<<endl;for(int i=1;i<=2*num-1;i++){for(int j=0;T[i][j]!='\0';j++){if(T[i][j]==' ')//空格printf(" "),fputc(T[i][j],fp);else//字符printf("%u",T[i][j]),fprintf(fp,"%u",T[i][j]);}cout<<endl;fputc(10,fp);}fclose(fp);return ;
}

主函数部分:

int main()
{char a[100]; //存储要编码的所有字符char b[400];  //存储要翻译的二进制编码char c[100]; //存储翻译出来的结果HuffmanTree HT=NULL;char ** HC;while(1){char s1[]= {"结点"},s2[]= {"字符"},s3[]= {"权值"},s4[]= {"双亲"},s5[]= {"左孩子"},s6[]= {"右孩子"};int flag=1,choose,num,cc=0;menu();char temp;cout<<"选择操作:";cin>>choose;switch(choose){case 1:cout<<"输入字符个数:";cin>>num;cout<<"依次输入"<<num<<"个字符:";for(int i=1; i<=num; i++)cin>>a[i];cout<<"依次输入"<<num<<"个字符的权值:";CreatHuffmanTree(HT,num);//cout<<"结点i"<<"\t字符"<<"\t权值"<<"\t双亲"<<"\t左孩子"<<"\t右孩子"<<endl;//for(int i=1; i<=num*2-1; i++)//cout<<i<<"\t"<<a[i]<<"\t"<<HT[i].weight<<"\t"<<HT[i].parent<<"\t"<<HT[i].lchild<<"\t"<<HT[i].rchild<<endl;FILE *fp;if((fp=fopen("hfmtree.txt","w"))==NULL)cout<<"error"<<endl;fwrite(&s1,sizeof(s1),1,fp);fwrite(&s2,sizeof(s2),1,fp);fwrite(&s3,sizeof(s3),1,fp);fwrite(&s4,sizeof(s4),1,fp);fwrite(&s5,sizeof(s5),1,fp);fwrite(&s6,sizeof(s6),1,fp);fputc(10,fp);//10=/nfor(int i=1; i<=2*num-1; i++){fprintf(fp,"%-3d  ",i);fwrite(&a[i],1,1,fp);/*fprintf(fp,"    %-3d    ",HT[i].weight);fprintf(fp,"%-3d    ",HT[i].parent);fprintf(fp,"%-3d    ",HT[i].lchild);fprintf(fp,"%-3d    ",HT[i].rchild);fputc(10,fp);*/}fclose(fp);break;case 2:CreatHuffmanCode(HT,HC,num);cout<<"结点i\t"<<"字符\t"<<"权值\t"<<"编码\t"<<endl;for(int i=1; i<=num; i++)cout<<i<<"\t"<<a[i]<<"\t"<<HT[i].weight<<"\t"<<HC[i]<<endl;break;case 3:Coding(HT,HC,num,a);cout<<"二进制编码已存入codefile.txt"<<endl;break;case 4:cout<<"从codefile.txt文件中读取进行译码:"<<endl;if((fp=fopen("codefile.txt","rb"))==NULL)cout<<"error"<<endl;while(1){temp = fgetc(fp); //读一个字节。if(temp == EOF) break; //到文件尾,退出循环。b[cc++] =temp ;//赋值到字符数组中。}b[cc]='\0';printf("%s\n",b);fclose(fp);TransCode(HT,b,a,c,num);cout<<"译码结果:";printf("%s\n",c);cout<<"翻译结果已存入textfile.txt"<<endl;break;case 5:printf_code();break;case 6:cout<<"打印哈夫曼树:"<<endl;printf_tree(num,HT);break;case 7:flag=0;break;default:cout<<"输入有误,重新输入"<<endl;continue;}if(flag==0)break;}return 0;
}

数据结构课程设计-(三)哈夫曼编码器相关推荐

  1. 【课程设计|C++】设计一个哈夫曼编码器/译码器设计

    目录 前言 设计一个哈夫曼编码器/译码器设计 [基本功能] [基本要求] 代码 实验结果 结语 前言 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出-   自我介绍 ଘ(੭ˊ ...

  2. 数据结构课程设计报告——Huffman编码

    目录 一. 问题描述与要求 二. 需求分析 三. 设计 3.1 设计思想 3.1.1 数据与操作的特性 3.1.2 数据结构设计 3.1.3 算法设计 3.2 设计表示 3.2.1 函数调用关系图 3 ...

  3. 哈夫曼编码器“数据结构课程设计”

    哈夫曼编码器 程序介绍 程序整体设计思想 程序详解 数据结构 动态存储 静态存储 编码译码 编码核心思想 核心代码 译码核心思想 核心代码 哈夫曼树可视化 核心思想 核心代码 完整代码 头文件 mai ...

  4. 数据结构课程设计-哈夫曼编解码器

    哈夫曼编解码器 最近在整理课程资料,就决定将自己完成的数据结构课程设计上传到CSDN里面. (1)问题描述 使用哈夫曼编码,实现文本文件的编码和解码,具体要求如下: ① 文本文件 data.txt 中 ...

  5. 数据结构课程设计之项目三---算术表达式求解

    目录 问题描述 基本要求 问题分析 逻辑设计 物理设计 存储结构 其他模块功能核心函数伪代码 总结 问题描述 设计一个简单的算术表达式计算器. 基本要求 实现标准非负整数类型的四则运算中缀表达式的求值 ...

  6. 数据结构课程设计[2023-01-19]

    数据结构课程设计[2023-01-19] 数据结构课程设计 一.课程设计要求 实现指定的题目(学号最后两位%4+1),并撰写课程设计报告. 独立完成,功能不完备也没关系,只要是自己做的 使用 C.C ...

  7. 大学数据结构课程设计题目

    数据结构课程设计题目 1.         飞机订票系统(限1 人完成) 任务:通过此系统可以实现如下功能: 录入: 可以录入航班情况(数据可以存储在一个数据文件中,数据结构.具体数据自定) 查询: ...

  8. C/C++数据结构课程设计安排

    C/C++数据结构课程设计安排 数据结构课程设计安排 课程设计学时:32学时 课程设计目的:综合应用数据结构课程中所学的数据结构:线性表.栈.队列.数组.广义表.树.二叉树.图.查找表中的一种或多种数 ...

  9. “数据结构”课程设计题目

    "数据结构"课程设计题目 1.城市链表 [问题描述] 将若干城市的信息,存入一个带头结点的单链表.结点中的城市信息包括:城市名,城市的位置坐标.要求能够利用城市名和位置坐标进行有关 ...

  10. 数据结构与算法学习④(哈夫曼树 图 分治回溯和递归)

    数据结构与算法学习④(哈夫曼树 图 回溯和递归 数据结构与算法学习④ 1.哈夫曼树 1.1.相关概念 1.2.哈夫曼树的构建 1.3.哈夫曼编码 1.4.面试题 2.图 2.1.图的相关概念 2.2. ...

最新文章

  1. django-request对象
  2. 【云计算】Docker删除名称为none的Image镜像
  3. 白牌交换机有什么特点?与传统换机相比有什么特别之处?
  4. OpenWrt启动过程分析+添加自启动脚本【转】
  5. Python之多进程
  6. 工业POE交换机使用中的常见问题汇总
  7. uni-calendar更改打点颜色实现签到和缺勤不同打点颜色效果
  8. java final 初始化_[转]java static final 初始化
  9. 20172313 2018-2019-1 《程序设计与数据结构》第六周学习总结
  10. 在游戏设备上砸钱 其实小姐姐们更疯狂!
  11. java post 403_求助啊。。。。。。给服务器POST JSON报403
  12. 怎么在Linux系统下使用NTFS的U盘或者是分区以及移动硬盘-使用工具NTFS-3G
  13. ILSpy .NET反编译工具下载地址
  14. 用c语言打印乘法口诀表
  15. java正则判断11位手机号码_java-正则表达式判断手机号
  16. DVD to MP4视频格式转换器v3.1.0 中文版
  17. 渗透测试-伪装隐藏与清理痕迹手段
  18. 【仿美团点餐App】—— 首页(一)
  19. C语言——链表拆分,奇数组成一个链表,偶数组成另外一个链表
  20. MyBatis-第三章 动态SQL

热门文章

  1. 从各方面比较一下各类电脑玩手游吃鸡安卓模拟器
  2. 北理在线作业答案c语言,北理乐学C语言答案,最新.doc
  3. mysql 联合查询_MySQL联合查询
  4. Spring定时器cron表达式
  5. linux下telnet工具下载,telnet.exe下载
  6. 手游php,PHP响应式手游APP软件游戏中心下载网站整站源码(自适应手机移动端) dedecms内核...
  7. Onenote插件,云扩容
  8. windows64位搭建汇编(包含汇编dosbox , masm文件,link文件和debug调试)以及debug调试命令(dosbox调试汇编程序的简单使用教程)
  9. 水利水电水资源模拟试题3
  10. [黑科技] 使用Word和Excel自制题库自判断答题系统