哈夫曼树,又称最优树,是一类带权路径最短的树。

哈夫曼树和哈夫曼的存储表示:

typedef struct{unsigned int weight;unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;//动态分配数组存储哈夫曼树
typedef char **HuffmanCode;//动态分配数组存储哈夫曼编码表

应用:

【问题描述】

利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传输数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼的编/译码系统。

【基本要求】

一个完整的系统应具有以下功能:

(1) I:初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。

(2) E:编码(Encoding)。利用以建好的哈夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。

(3) D:译码(Decoding)。利用已经建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。

(4) P:打印代码文件(Print)。将文件CodeFile以紧凑格式显示在终端上,每行50个代码,同时将此字符形式的编码写入文件CodePrint中。

(5) T:打印哈夫曼树(Tree printing)。将已经在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。

【测试数据】

(1) 利用教科书例6-2中的数据调试程序。

(2) 用下表给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的编码和译码:“THIS PROGRAM IS MY FAVORITE”。

字符

A     B    C    D     E    F    G    H    I    J    K     L    M

频度

186   64    13    22   32  103    21   15   47   57   1    5     32   20

字符

N     O     P    Q    R     S    T    U    V    W    X    Y     Z

频度

57    63    15    1    48    51   80   23   8    18   1    16    1

【实现提示】

(1) 编码结果以文本式存储在文件CodeFile中。

(2) 用户界面可以设计为“菜单”方式:显示上述功能符号,再加上“Q”,表示退出运行Quit。请用户键入一个选择功能符。此功能执行完毕后再显示此菜单,直至某次用户选择了“Q”为止。

(3) 在程序的一次执行过程中,第一次执行I,D或C命令之后,哈夫曼树已经在内存了,不必再读入。每次执行中不一定执行I命令,因为文件hfmTree可能早已建好。

【选作内容】

(1) 上述文件CodeFile中的每个“0”或“1”实际上占用了一个字节的空间,只起到示意或模拟的作用。为最大限度地利用码点存储能力,试改写你的系统,将编码结果以二进制形式存放在文件CodeFile中。

(2) 修改你的系统,实现对你的系统的源程序的编码和译码(主要是将行尾符编/译码问题)。

(3) 实现各个转换操作的源/目的文件,均由用户在选择此操作时指定。

#include<iostream.h>
//using namespace std;
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<fstream.h>
#define num 1000
typedef struct//哈夫曼树的结构体
{char ch;int weight;//权值int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char **HuffmanCode;
void Select(HuffmanTree &HT,int a,int *p1,int *p2)
//Select函数,选出HT树到a为止,权值最小且parent为0的2个节点
{int i,j,x,y,count,temp;for(j=1,count=1;j<=a;j++){if(HT[j].parent==0){if(count==1)x=j;if(count==2)y=j;count++;            }if(count>2)break;}if(HT[x].weight>HT[y].weight)//令x结点权值小于y结点权值
    {temp=y;y=x;x=temp;}i=(x>y?x:y)+1;while(i<=a){if(HT[i].parent==0){if(HT[i].weight<HT[x].weight){y=x;x=i;}else{if(HT[i].weight>=HT[x].weight&&HT[i].weight<HT[y].weight)y=i;}}i++;}*p1=HT[x].weight<=HT[y].weight?x:y;*p2=HT[x].weight>HT[y].weight?x:y;}
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int n)//构建赫夫曼树HT,并求出n个字符的赫夫曼编码HC
{int i,start,c,f,m,w;int p1,p2;char *cd,z;if(n<=1)exit(1);m=2*n-1;//n个叶子结点的哈夫曼树共有2n-1个结点HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未使用for(i=1;i<=n;i++)//初始化n个叶子结点
    {printf("请输入第%d字符信息和权值:",i);scanf("%c%d",&z,&w);while(getchar()!='\n'){continue;}HT[i].ch=z;HT[i].weight=w;HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;}for(i=n+1;i<=m;i++)//初始化其余结点
    {HT[i].ch='0';HT[i].weight=0;HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;}for(i=n+1;i<=m;i++)//建立哈夫曼树
    {Select(HT,i-1,&p1,&p2);HT[p1].parent=i;HT[p2].parent=i;HT[i].lchild=p1;HT[i].rchild=p2;HT[i].weight=HT[p1].weight+HT[p2].weight;}//从叶子到根逆向求每个字符的哈夫曼编码HC=(HuffmanCode)malloc((n+1)*sizeof(char *));cd=(char *)malloc(n*sizeof(char));cd[n-1]='\0';for(i=1;i<=n;i++){start =n-1;for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent){if(HT[f].lchild==c)cd[--start]='0';elsecd[--start]='1';}HC[i]=(char *)malloc((n-start)*sizeof(char));strcpy(HC[i],&cd[start]);}free(cd);
}
int main()
{char code[100],h[100],hl[100];int n,i,j,k,l;ifstream input_file; ofstream output_file;FILE *fp1,*fp2,*fp3,*fp4,*fp5;char choice,str[100];HuffmanTree HT;HuffmanCode HC;cout<<"            哈夫曼编码器\n";while(choice!='Q'&&choice!='q')            //当choice的值不为q且不为Q时循环
    {cout<<"功能: "<<"I(初始化)"<<""<<"E(编码)"<<""<<"D(译码)"<<""<<"P(打印)"<<""<<"Q(退出)\n";cout<<"请输入您要选择的功能:";cin>>choice;if(choice=='I'||choice=='i')              //初始化赫夫曼树
        {cout<<"请输入字符个数:";cin>>n;HuffmanCoding(HT,HC,n);for(i=1;i<=n;++i){cout<<HT[i].ch<<":"<<HC[i]<<endl;}fp1=fopen("hfmTree.txt","w");for(i=1;i<=n;++i){fprintf(fp1,"(%c %s)\n",HT[i].ch,HC[i]);}fclose(fp1);cout<<"赫夫曼树已经创建完毕,并且已经放入hfmTree.txt文件中!"<<endl;}else if(choice=='E'||choice=='e')           //进行编码,并将字符放入ToBeTran.txt,码值放入CodeFile.txt中
        {printf("请输入字符:");gets(str);fp2=fopen("ToBeTran.txt","w");fprintf(fp2,"%s",str);fclose(fp2);fp3=fopen("CodeFile.txt","w");for(i=0;i<strlen(str);i++){for(j=1;j<=n;++j){if(HT[j].ch==str[i]){fprintf(fp3,"%s",HC[j]);break;}}}fclose(fp3);cout<<"\n";fp4=fopen("CodeFile.txt","r"); char H1;//从CodeFile.txt中读入编码,输出在终端cout<<"编码值为:\n";while(!feof(fp4)){H1=fgetc(fp4);cout<<H1;}fclose(fp4);cout<<"\n编码完毕,并且已经存入CodeFile.txt文件!\n";}else if(choice=='D'||choice=='d')     //读入CodeFile.txt中的编码进行译码,将译出来的字符放入Textfile.txt中
        {input_file.open("CodeFile.txt");if(!input_file){cout<<"can't open file!"<<endl;return 1;}input_file>>h;input_file.close();output_file.open("Textfile.txt");if(!output_file){cout<<"can't open file!"<<endl;return 1;}k=0;while(h[k]!='\0')           //先用编码中的前几个和字符的编码相比较,然后往后移
            {for(i=1;i<=n;i++){l=k;for(j=0;j<strlen(HC[i]);j++,l++){hl[j]=h[l];}hl[j]='\0';if(strcmp(HC[i],hl)==0){output_file<<HT[i].ch;k=k+strlen(HC[i]);break;}}}output_file.close();input_file.open("Textfile.txt");if(!input_file){cout<<"can't open file!"<<endl;return 1;}//    input_file>>h;input_file.getline(h,100);//获取文件里的一行cout<<"译码结果为:";printf("%s\n",h);input_file.close();cout<<"译码结果已存入Textfile.txt中\n";}else if(choice=='P'||choice=='p')//每行50个代码
        {char a[num];fp4=fopen("CodeFile.txt","r"); fgets(a,num,fp4);cout<<"打印代码文件:"<<endl;int l=strlen(a);for(int j=0;j<l;j++){cout<<a[j];if((j+1)%50==0)cout<<endl;}fclose(fp4);fp5=fopen("CodePrint.txt","w");for(int k=0;k<l;k++){fprintf(fp5,"%c",a[k]);if((k+1)%50==0){fprintf(fp5,"\n");}}cout<<"\n该字符形式已存入CodePrint.txt中\n";fclose(fp5);}else if(choice=='Q'||choice=='q')            //退出程序
        { exit(0);}else               //如果选了选项之外的就让用户重新选择
        {cout<<"您没有输入正确的步骤,请重新输入!"<<endl;}cout<<endl;}return 0;
}

用上的几个文本需要自己新建。

转载于:https://www.cnblogs.com/wuhenxiansen/p/10390400.html

哈夫曼树的构建及应用相关推荐

  1. 【算法学习笔记】哈夫曼树的构建和哈夫曼编码的实现代码

    介绍 哈夫曼(Haffman)这种方法的基本思想如下: ①由给定的n个权值{W1,W2,-,Wn}构造n棵只有一个叶子结点的二叉树,从而得到一个二叉树的集合F={T1,T2,-,Tn}. ②在F中选取 ...

  2. JAVA实现二叉树带权路径长度和_哈夫曼树的构建与最小带权路径长度

    注意:哈夫曼树并不唯一,但带权路径长度一定是相同的. 二叉树:每个结点最多含有两个子树的树称为二叉树. 定理:对于具有n个叶子结点的哈夫曼树,共有2n-1个结点. 哈夫曼树介绍 1哈夫曼树的定义 哈夫 ...

  3. 哈夫曼树的构建及哈夫曼树编码

    哈夫曼树的构建: 注意:(1).首先把一组数3 5 6 8 9 12 15从小到大排列 (2).选取里面最小2个,顶点出为2个数的和 (3).新产生的顶点在与原先的数字进行比较,在里面选取2个最小的数 ...

  4. 一文了解赫夫曼树的构建与赫夫曼编码

    文章目录 一.赫夫曼树 基本介绍 赫夫曼树几个重要概念和举例说明 赫夫曼树创建步骤图解 代码构建赫夫曼树 二.赫夫曼编码 1基本介绍 通信领域中的信息的处理方式1-定长编码 通信领域中的信息的处理方式 ...

  5. 哈夫曼树的构建、编码以及带权路径长计算

    给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的结点离根较 ...

  6. 【id:179】【20分】C. DS二叉树--赫夫曼树的构建与编码(不含代码框架)

    题目描述 给定n个权值,根据这些权值构造huffman树,并进行huffman编码 参考课本P147算法6.12 HuffmanCoding代码,注意数组访问是从位置1开始 要求:赫夫曼的构建中,默认 ...

  7. Python---哈夫曼树---Huffman Tree

    今天要讲的是天才哈夫曼的哈夫曼编码,这是树形数据结构的一个典型应用. !!!敲黑板!!!哈夫曼树的构建以及编码方式将是我们的学习重点. 老方式,代码+解释,手把手教你Python完成哈夫曼编码的全过程 ...

  8. 赫夫曼树建立c语言源程序编译结果详细解释,哈夫曼树的建立与实现最终版(备份存档)...

    <哈夫曼树的建立与实现.doc>由会员分享,可免费在线阅读全文,更多与<哈夫曼树的建立与实现(最终版)>相关文档资源请在帮帮文库(www.woc88.com)数亿文档库存里搜索 ...

  9. python哈夫曼树_python霍夫曼树

    class Node(): data=0 left=None right=None father=None def __init__(self,data,left,right): self.data= ...

最新文章

  1. Javascript Tip(1) 操作剪贴板
  2. 分布式系统的事务处理(推荐)
  3. Python(四)字符串
  4. c语言贪吃蛇游戏编程视频教程,C语言贪吃蛇游戏精典源码 - 视频教程 - VC中文网-VC-MFC编程论坛 - Powered by Discuz!...
  5. Activiti获取当前活动(任务)的出口(动态生成提交按钮)
  6. windows Server 2016 开启远程登录和多用户同时远程登录
  7. INNO SETUP卸载程序中加入自定义窗体
  8. 【浙江第16届省赛:B】Element Swapping(分情况讨论--数学题)
  9. 分式智能计算机在线计算,全能智能计算器
  10. 如何做好网站的安全性测试
  11. 自己制作的直流电机驱动器
  12. 图片文件,图片文件流和BASE64加密字符串之间的转换,以及图片的BASE64加密字符串再jsp上如何显示
  13. Unsupervised Domain Adaption of Object Detectors : A Survey
  14. 树莓派2代B型性能极限测试
  15. 【VPP】 VPP之DPO
  16. 使用vue报错Cannot use ‘in‘ operator to search for
  17. [转载]MIDAS/Gen常见问题汇编(一) 转自百思论坛
  18. mybatis高级映射一对多查询(一)
  19. 半导体器件物理【13】载流子输运现象 —— 霍尔效应
  20. 工作记录:docker

热门文章

  1. windows10删除EFI分区(绝对安全)
  2. 小米手机开启“启用MIUI优化”,导致Android Studio无法成功直接安装
  3. 使用eNSP搭建两个交换机通过trunk实现相同vlan互联
  4. 【算法设计与分析】递归与分治 | 复习笔记
  5. 如何优雅地跟老板请假?
  6. linux svn 查看忽略文件
  7. 小把戏之——用电脑或手机打出拼音带音标!
  8. 基于重构误差的同构图分类模型
  9. 计算机网络之Dos、DDos攻击
  10. CISCO-路由器交换机密码恢复