哈夫曼编码和译码
基本要求:
 输入为:一段英文或中文的文章(原文)
 对输入的文章构造哈夫曼树生成对应的编码
 输出为:原文所对应的编码(译文)
 根据已经生成的编码表,输入任意的译文可以得到对应的原文

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

首先先构造一棵哈夫曼树,在构造哈夫曼树的算法中,需要选择根权值最小和次小的树进行合并

//建立哈夫曼树编码表void HuffmanTree::CreatHuffmanTree(int a[],char b[],int n)
{int m=2*n-1;nodes= new HuffmanTreeNode[2*n-1];//开辟数组空间for(int i=0;i<n;i++)         //初始化结点为-1{nodes[i].weight=a[i];    //函数头定义的权值数组a[]nodes[i].leftChild=-1;        nodes[i].rightChild=-1;         nodes[i].parent=-1;       }for(i=n; i<m;i++)         {int r1=0,r2=0;select(r1,r2,i); //合并两个根权值最小的树nodes[r1].parent=nodes[r2].parent=i;nodes[i].leftChild=r1;nodes[i].rightChild=r2;nodes[i].parent=-1;nodes[i].weight=nodes[r1].weight+nodes[r2].weight;     }//查找两个权值最小的树
void HuffmanTree::select(int &r1,int &r2,int n)
{r1=r2=-1;                              for(int i=0; i<n; i++)if(nodes[i].parent==-1)  //找权值最小的双亲节点         if(r1==-1)r1=i;else
if(nodes[r1].weight<nodes[i].weight)
{   r2=r1;//r2等于次小的r1=i;//r1等于最大的}else if(r2==-1||nodes[i].weight<nodes[r2].weight)//找权值第二小的结点r2=i;
}```cpp
在这里插入代码片

建立编码表,根据每一根分支是左还是右,确定相应位编码是0还是1(此代码为左0右1),从叶子节点出发逆向到根结点,将编码倒转使之成为正确的编码

//建立编码表
void HuffmanTree::CreatHuffmanTree(int a[],char b[],int n)
{codes=new HuffmanCode[n];        for( i=0; i<n; i++){codes[i].data=b[i];//将编码后的结果储存在b数组中int q=i;int p=nodes[i].parent;//p指向结点i的双亲int k=0;while(p!=-1)//逆向求码{if(q==nodes[p].leftChild)codes[i].code[k]='0';   //左0elsecodes[i].code[k]='1';    //右1k++;//向下往上查找双亲q=p;p=nodes[q].parent;}codes[i].code[k]='\0';recall(codes[i].code,k);  //字符串整合,倒转cout<<codes[i].data<<"的编码是:"<<codes[i].code<<endl;}
}//倒转字符串
void HuffmanTree::recall(char c[],int L)
{L=0;char temp;while(c[L+1]!='\0')//获取当前编码的长度{L++;}for(int i=0;i<=L/2;i++)//交换位置{temp=c[i];c[i]=c[L-i];c[L-i]=temp;}
}

有了哈夫曼树的编码,即可进行编码和译码

//编码
void HuffmanTree::Encode(char *c, char *s,int n)
{while(*c!='\0')                   {for(int i=0;i<=n-1;i++)   //遍历查找编码{if(*c==codes[i].data)   {strcat(s,codes[i].code);//复制连接字符串break;}}c++;}cout<<"编码结果为:"<<s<<endl;
}//译码
void HuffmanTree::Decode(char *s, char *d,int n)
{int z=2*n-2;char *p=d;                                 while(*s!='\0')//编码的逆过程{                                     while(nodes[z].leftChild!=-1)  {if(*s=='0')  //如果*s==0,给根结点的左孩子的下标值赋值z并把左孩子作为新的根结点                        z=nodes[z].leftChild;//左0else if(*s=='1')z=nodes[z].rightChild;//右1s++;}*d=codes[z].data;//译码后的结果赋值给指针*dd++;}cout<<endl<<"译码结果为:"<<p<<endl;
}

主要函数就是以上,下面将程序变得完整一点,使其成为可运行的程序
主函数如下:

void  main()
{   HuffmanTree HT;  //system("color b0");//system("color f4");cout<<"---------------------------------------"<<endl;    cout<<"      欢迎使用哈夫曼编码系统          "<<endl;  cout<<"---------------------------------------"<<endl;  cout<<"         请输入英文段落:       "<<endl;char *A1=new char[50];//定义字符指针,开辟空间设置字符长度char *B1=new char[50];*B1='\0';//字符串结束标志gets(A1);//得到从键盘输入的字符串A1int n = HT.sumweight(A1);//计算A1字符串的频率char *A2=new char[50];for(int i=0;i<=49;i++)*(A2+i)='\0';    //到A2+1个字符结束cout<<"按任意字符继续。"<<endl;getch();HT.menu();while(true)                     {int w;cin>>w;switch(w){case 1:HT.CreatHuffmanTree(I,H,n);getch();             cout<<"按任意字符继续。"<<endl;//system("cls");可选择清屏或不清屏HT.menu();break;case 2:HT.Encode(A1,B1,n);cout<<"按任意字符继续。"<<endl;getch();   //system("cls");HT.menu();break;case 3:gets(B1);cout<<endl<<"请输入想要翻译的一串二进制编码:"<<endl;gets(B1);HT.Decode(B1,A2,n);cout<<"按任意字符继续。"<<endl; getch();//system("cls");HT.menu();break;case 4:cout << endl;cout << "退出成功!" << endl;                    exit(0);break; default:                cout<<"选择失败,请重新选择!"<<endl;cout<<endl;break;}}
}

哈夫曼树是带权路径长度最小的树,所以将一段英文里出现字符的频率作为权值来计算


//计算字符出现的频率
int HuffmanTree::sumweight(char *pl)
{char *sweight=pl;int i=0;H[0]=*sweight;I[0]=0;while(*sweight!='\0'){for(int j=0;j<=i;j++)           {if(H[j]==*sweight){I[j]++;break;}}     if(j>i)                 {i++;H[i]=*sweight;I[i]=1;}sweight++;}cout<<endl<<"统计次数:"<<endl;for(int j=0;j<=i;j++)cout<<"字符"<<H[j]<<"的频率为"<<I[j]<<endl;return i+1;
}

至此,程序基本已经完善,剩下的函数成员以及结构体可在调试时自行加上。

数据结构实训哈夫曼树相关推荐

  1. 数据结构实验之——哈夫曼树的实现

    数据结构实验之--哈夫曼树的实现 目录 说明 代码 测试用例 目录 说明 哈夫曼树的这个实验我是采用常用的左'0'右'1'来实现的,输入是用文本输入的,大家在用之前目录下要记得创建"HT.t ...

  2. 数据结构学习记录——哈夫曼树(什么是哈夫曼树、哈夫曼树的定义、哈夫曼树的构造、哈夫曼树的特点、哈夫曼编码)

    目录 什么是哈夫曼树 哈夫曼树的定义 哈夫曼树的构造 图解操作 代码实现 代码解析 哈夫曼树的特点 哈夫曼编码 不等长编码 二叉树用于编码 哈夫曼编码实例 什么是哈夫曼树 我们先举个例子: 要将百分制 ...

  3. 数据结构与算法 / 霍夫曼树、霍夫曼编码和解码

    一. 诞生原因 找出存放一串字符所需的最少的二进制编码. 二. 构造方法 首先统计出每种字符出现的频率,即:概率.权值. 例如:频率表 A:60,    B:45,   C:13   D:69   E ...

  4. 【大话数据结构算法】哈夫曼树

    哈夫曼树又称为最优二叉树. 1.路径和路径长度 在一棵树中,从一个节点往下可以达到的孩子或者子孙节点之间的通路称为路径.通路中分支的数目称为路径长度.若规定根节点的层数为1,则从根节点 到第L层节点的 ...

  5. 数据结构与算法--哈夫曼树应用

    第1关:统计报文中各个字符出现的次数 任务描述 本关任务: 给定一串文本,统计其中各个字符出现的次数: 测试说明 平台会对你编写的代码进行测试: 测试输入:` abcdeabcdeabcdabcdab ...

  6. 数据结构与算法--哈夫曼树及其应用

    一.哈夫曼树的基本概念 1) 路径: 从树中一个结点到另一个结点之间的分支构成这两个结点间的路径 2) 结点的路径长度: 两结点间路径上的分支数           3) 树的路径长度:从树根到每一个 ...

  7. 数据结构课程设计-哈夫曼树及其应用

    题目:假设用于通信的电文由字符集{a,b,c,d,e,f,g,h,}中的字母构成,这8个字母在电文中出现的 频率分别为: {0.19, 0.21, 0.02, 0.03, 0.06, 0.07, 0. ...

  8. 数据结构与算法——赫夫曼树基本实现

    目录 一.赫夫曼树 1.1 基本介绍 1.2 赫夫曼树创建步骤图解 1.3  代码实现 二.赫夫曼编码 2.1 基本介绍 2.1.1  通讯领域 - 定长编码 - 举例说明 2.1.2  通讯领域 - ...

  9. 数据结构与算法(赫夫曼树,赫夫曼编码)

    赫夫曼树 基本介绍: (1)给定n个权值作为n给叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为最优二叉树,也称哈夫曼树(HuffmanTree),还有的树翻译为霍夫 ...

最新文章

  1. Python计算机视觉——图像到图像的映射
  2. 总结网络执法官,p2p终结者等网管软件使用arp欺骗的防范方法
  3. 2019中国独角兽新增数锐减62%,仅有22家;美国新增78家,占全球大半
  4. java的集合:List、Set和Map
  5. MySQL子查询优化思路
  6. cocos2d-x初探学习笔记(9)--粒子系统
  7. 计算机工作原理 仿真,虚拟DCS仿真工作原理
  8. 一头华发梳得整齐,一袭素衣低调谦逊。她是著名的环境工程专家清华第一位女院士钱易教授。...
  9. 五种编程语言解释数据结构与算法——顺序表3(JavaScript与Python语言实现)
  10. chrome 设置是否缓存
  11. SqlServer查询表中某列相同值的最近记录
  12. scrollView滚动原理
  13. C语言两个数比较大小和三个数比较大小,代码
  14. php 姓名校验 根据百家姓
  15. 解决在微信中不能直接发送和下载APK的方案
  16. 面试官:生产环境中 CPU 利用率飙高怎么办?
  17. CMS漏洞检测工具 – CMSmap
  18. 数据库系统原理与应用教程(081)—— MySQL 视图(View)的创建与使用
  19. python下的一个好用的日历库,支持农历和公历互转,是一个很好用的日期包
  20. 在所难免!我也阳了。。

热门文章

  1. 【C#】【报错解决】分析器错误消息: 无法识别的属性“targetFramework”。请注意属性名称区分大小写。...
  2. 如何使IE打开最大化?
  3. 使用js完成注册页面验证-注册有返回值的onsubmit事件函数
  4. 自从上了 Prometheus 监控!睡觉踏实多了
  5. 周志华《机器学习》课后习题解答系列(三):Ch2 - 模型评估与选择
  6. 变电站通信网络和系统协议IEC61850介绍
  7. matplotlib绘图宋体
  8. 11g使用增量备份来执行跨平台传输表空间减少停机时间(xtts_rman)
  9. python爬取中国大学(高校)基本信息
  10. 【Leetcode】589. N叉树前序遍历