一、编程目的

(1)学习和理解树和二叉树的概念、特点和相关知识,理解和掌握二叉树的遍历操作的原理和方法;掌握二叉树的常用存储结构以及C++类的实现方法。

(2)学习最优二叉树的概念,理解和掌握哈夫曼算法的原理,掌握基于哈夫曼算法构造最优二叉树的方法;学习和掌握基于最优二叉树的哈夫曼编码方法。

(3)学会通过分析应用需求,结合理论知识来设计合理的数据结构与有效的求解算法;能够通过查找和学习技术资料、文档来掌握需用到的编程知识、技术;能够综合运用所学知识,利用开发环境提供的调试工具对程序进行调试,完成程序的开发、测试和完善。

二、26字母频率表

英文字母字符集及使用频率

字母

英语中出现的频率

字母

英语中出现的频率

字母

英语中出现的频率

字母

英语中出现的频率

a

8.167%

h

6.094%

o

7.507%

u

2.758%

b

1.492%

i

6.966%

p

1.929%

v

0.978%

c

2.782%

j

0.153%

q

0.095%

w

2.360%

d

4.253%

k

0.772%

r

5.987%

x

0.150%

e

12.702%

l

4.025%

s

6.327%

y

1.974%

f

2.228%

m

2.406%

t

9.056%

z

0.074%

g

2.015%

n

6.749%

三、代码实现

#include <iostream>
#include<iomanip>
#include<string.h>
using namespace std;
struct huff
{double weight;int parent, lch, rch;char cha;
};
struct code
{char cd[25];int start;
};
void input(huff hufftree[],char alpha[],double weight[])//初始化哈夫曼树,权值先全部赋0,再将频率录入
{for (int i = 0;i < 51;i++)hufftree[i].cha = '_';for (int i = 0;i < 26;i++)hufftree[i].cha= alpha[i];for (int i = 0;i < 51;i++)hufftree[i].weight = 0;for (int i = 0;i < 26;i++)hufftree[i].weight = weight[i];for (int i = 0;i < 51;i++){hufftree[i].parent = -1;hufftree[i].lch = -1;hufftree[i].rch = -1;}
}
void buildtree(huff hufftree[])
{int i, k, lnode, rnode;double mina, minb;for (i = 26;i < 51;i++)//从第一个结点开始,确定其孩子结点{mina = minb = 100;lnode = rnode = 0;//100和0只是初始化值,无特殊含义,取100是确保高于任意字母的频率,因为所有字母的频率和是100for (k = 0;k < 51&&hufftree[k].weight!=0;k++)//每一次遍历整个hufftree,将已经找到双亲结点的和尚未被使用的结点剔除,比较剩余结点{if (hufftree[k].parent == -1)//没找到双亲结点{if (hufftree[k].weight < mina)//每一轮后mina都会变为100,此时基本第一个进来的k就会执行这个if语句{minb = mina;//如果后续有更小的权,原先在mina的数据便会被移动到minb,暂时变为第二小rnode = lnode;mina = hufftree[k].weight;lnode = k;}else if (hufftree[k].weight < minb)//看看新的权值会不会替代成为第二小{minb = hufftree[k].weight;rnode = k;}//遍历整个hufftree后,此时mina和minb上都已经确定好这一轮的最小和次小,准备赋值给这一轮对应的未使用结点}}hufftree[lnode].parent = i;//确定双亲hufftree[rnode].parent = i;hufftree[i].weight = hufftree[lnode].weight + hufftree[rnode].weight;//确定未使用结点的权hufftree[i].lch = lnode;//确定未使用结点的孩子hufftree[i].rch = rnode;}//循环直到按照哈夫曼算法确定每个结点的值,构造完成}
void createcode(huff hufftree[],code alphac[])
{int i, f, c;code hc{};for(i=0;i<26;i++)//26次循环,确定26个字母{hc.start = 26;c = i;f = hufftree[i].parent;while (f != -1){if (hufftree[f].lch == c)hc.cd[hc.start--] = '0';else hc.cd[hc.start--] =  '1';c = f;f = hufftree[f].parent;//向上再找一级,逆向从后向前储存}hc.start++;//读取时有用,确定长度alphac[i] = hc;//储存}
}
void display(code alphac[],huff hufftree[])
{int i, j;cout << "*********             欢迎使用哈夫曼编码程序             *************" << endl;cout << "*********       26字母表字符集对应哈夫曼编码如下:       *************" << endl;for(i=0;i<26;i++){cout << hufftree[i].cha << " ";for (j = alphac[i].start;j <= 26;j++)cout << alphac[i].cd[j];//正向读取cout << endl;}cout << "*************   请输入接下来的操作:         *************" << endl;cout << "************     1.将单词翻译为哈夫曼编码         ********************" << endl;cout << "************     2.将哈夫曼编码翻译为单词         ********************" << endl;cout << "请选择:" << endl;
}
void fromwordstohuff(code alphac[], huff hufftree[])
{int eye = 0;cout << "请输入你想编译的单词:" << endl;char input[1000];cin >> input;cout << input << "的编码为:" ;for (int i = 0;input[i] != '\0';i++){char temp = input[i];for (int k = 0;k < 26;k++){if (temp == hufftree[k].cha){for (int j = alphac[k].start;j <= 26;j++)cout << alphac[k].cd[j];//正向读取eye++;}}}if (eye < strlen(input)){cout << endl;cout << "您输入的单词中或含非法字符,已过滤,请您留意!" << endl;//鲁棒性容错}cout << endl;
}
void fromhufftowords(code alphac[], huff hufftree[],char code[])
{cout<< "该编码对应单词为:" ;int i, j;struct array { char storecode[10]; };array array1[26];for (i = 0;i < 26;i++){int q = 0;for ( j = alphac[i].start;j <= 26;j++){array1[i].storecode[q] = alphac[i].cd[j];q++;}array1[i].storecode[q] = '\0';//cout << array1[i].storecode << endl;(调试用)}int tt=0;//用于暂存i值char codecmp[1000];//构造用于比较的字符串int z;int w = 0;for (int i = 0;code[i] != '\0';) {int key=1;//用于判断是否跳出for循环//cout << w;w++;system("pause");(调试用)tt = i;for (z = 0;code[i] != '\0';z++){codecmp[z] = code[i];i++;}//完成拷贝codecmp[z++] = '\0';//加入截止符号i = tt;int len=0;int k = 0;for (;k < 26&&key==1;k++){    int d;for (d = 0; codecmp[d] != '\0';) {   if (codecmp[d] == array1[k].storecode[d]){d++;if (array1[k].storecode[d] == '\0')//判断哈夫曼代码是否和字符集有相同的段落{cout << hufftree[k].cha;//如果有,输出该字符key = 0;//调整key,使得对于该字符的循环停止,重新从k=0开始,避免k继续往下加len = strlen(array1[k].storecode);}}else break;}}if (k == 26 && key == 1) {cout << "<——本条提示前为成功编译的字母,但此后存在哈夫曼码输入错误,请检查后重新输入" << endl;break;}i = i + len;key = 1;//重调key值是下一次正常进入循环}}
int main()
{int w; int t;char alpha[26] = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z' };double weight[26] = { 8.167,1.492, 2.782,4.253,12.702,2.228,2.015,6.094,6.966,0.153,0.772,4.025,2.406,6.749,7.507,1.929,0.095,5.987,6.327,9.056,2.758,0.978,2.360,0.150,1.974,0.074 };huff hufftree[51];code alphac[26];input(hufftree, alpha, weight);buildtree(hufftree);createcode(hufftree, alphac);display(alphac, hufftree);//字母表、权值表、哈夫曼树和储存哈夫曼码的结构数组的建立while(1){ cin >> t;w = t;int guard = 0;switch(w){case 1: fromwordstohuff(alphac, hufftree);break;case 2:  cout << "请输入哈夫曼码:" << endl;char code[1000];cin >> code;for (int check = 0;code[check] != '\0';check++){if (code[check] != '0' && code[check] != '1'){cout << "请输入二进制数字,请重试" << endl;guard = 1;break;}}if (guard == 1) { break; }fromhufftowords(alphac, hufftree,code);cout << endl;break;case 3: exit(1);default: cout << "请输入一个合理的选项" << endl;}cout << endl;cout << "*************   请输入接下来的操作:         *************" << endl;cout << "************     1.将单词翻译为哈夫曼编码         ********************" << endl;cout << "************     2.将哈夫曼编码翻译为单词         ********************" << endl;cout << "************     3.退出程序                       ********************" << endl;cout << "请选择:" << endl;}}

四、运行结果

1、初始化

2、将单词编码为哈夫曼编码

3、将哈夫曼码编译为单词

五、结语

源代码很少调用函数,编程习惯也很糟糕,因为笔者对c++已经非常生疏,但觉得这个功能很有意思,所以还是磕磕绊绊写出来了一堆非常低效低级的代码,有的地方甚至非常冗余,源代码看着乐就好啦!

笔者过于小白,如果觉得有任何错漏和不足,恳请批评指正笔者,笔者感激不尽!

哈夫曼算法编码26字母程序实现C++相关推荐

  1. 哈夫曼算法证明+哈夫曼编码译码程序实现

    哈夫曼算法证明 哈夫曼算法是一种贪心算法,我们考虑证明其最优子结构和贪心选择性质: 最优子结构:假设一个树是哈夫曼树,则以其任意节点为根节点的最大子树也是哈夫曼树. 证明:子树的根节点的值是其所有叶子 ...

  2. RLE算法机制、缺点及哈夫曼算法和莫尔斯编码

    CSDN话题挑战赛第2期 参赛话题:学习笔记 目录 一.RLE算法机制 二.RLE算法的缺点 三.哈夫曼算法和莫尔斯编码 一.RLE算法机制 对 AAAAAABBCDDEEEEEF 这17个半角字符的 ...

  3. 赫夫曼树编码的算法及应用习题--数据结构

    赫夫曼树编码的算法及应用习题 1.构造赫夫曼树的方法 1.根据给定的n个权值{w1,w2,---wn},构成n棵二叉树的集合F={T1,T2...,Tn},其中每棵二叉树中只有一个带权为Wi的根结点, ...

  4. 霍夫曼算法_霍夫曼编码算法

    霍夫曼算法 In this tutorial, we'll be discussing and implementing the Huffman Coding Algorithm in Java. 在 ...

  5. 数据结构哈夫曼树实现26个英文字符的编码和译码

    数据结构哈夫曼树实现26英文字符的编码和译码 那么首先什么是哈夫曼树?(知道的略过,直奔下面代码就好!) 在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编 ...

  6. 哈夫曼字符串编码c语言实现,基于哈夫曼(haffuman)算法的文件压缩的实现(C语言)(原创)...

    本文首先简要阐述哈夫曼算法的基本思想,然后介绍了使用哈夫曼算法进行文件压缩和解压缩的 处理步骤,最后给出了C语言实现的文件压缩和解压缩的源代码. 哈夫曼算法的主要思想是: ①首先遍历要处理的字符串,得 ...

  7. java哈夫曼树编码_哈夫曼树的编码实验

    Java哈夫曼编码实验--哈夫曼树的建立,编码与解码 建树,造树,编码,解码 一.哈夫曼树编码介绍 1.哈夫曼树: (1)定义:假设有n个权值{w1, w2, ..., wn},试构造一棵含有n个叶子 ...

  8. 利用C++实现哈夫曼算法

    我想每个计算机专业的学生或多或少都接触过哈夫曼编码,数据结构中的老问题了.大体就是给出一些字符,和这些字符的出现频率,让你为这些字符设计一个二进制编码,要求频率最高的字符的编码最短.解决的方法是构造一 ...

  9. 基于哈夫曼算法的文件压缩软件

    数据结构课设(一) 作业要求 1.设计并实现一个使用哈夫曼算法对文件进行压缩的工具软件. 2.通过命令行参数指定操作模式(压缩/解压).源文件名.目标文件名. 3.压缩操作将源文件按字节读入并统计字节 ...

最新文章

  1. 虚拟机安装CentOS以及SecureCRT设置【完美无错版】
  2. DVWA安装——一个菜鸟的入门教程
  3. 【设计思想解读开源框架】java如何发送post请求
  4. 替换ExpandableListView右边箭头Group Indicator(小图标)
  5. css不换行属性_那些不常见,但却非常实用的css属性(整理不易)
  6. java http 状态_Java HTTP连接似乎保持打开状态
  7. boost::callable_traits的is_rvalue_reference_member的测试程序
  8. 基本概念—回归、分类、聚类
  9. oracle实现主键自动增长
  10. Sass笔记(CSS 的预编译语言)
  11. html地址--待更新
  12. 来看看 ETL 和数仓建模的设计思路!
  13. IOS视频播放器的使用(MPMoviePlayerController)
  14. 趣挨踢 | 只有挨踢人才能读懂的西游记
  15. C语言实现埃拉托色尼筛选法(剔除数组中的非质数)
  16. SEO人员快速提升关键词优化排名的方法
  17. java中方法的细分(普通方法,静态方法,构造方法)
  18. 5G基带芯片之战现状:一二三分别对应联发科华为高通
  19. 图算法入门4:活动网络-AOE网络和关键路径(critical path)
  20. GB28181-2016 协议(一)

热门文章

  1. xpspeak安装教程_查漏补缺:教你正确操作 XPS 分峰软件 XPSPEAK
  2. java 下载excel问题
  3. 微信小程序运动步数java_微信小程序实现运动步数排行(可删除)
  4. php搜索表格,table表格内对某列内容进行搜索筛选步骤详解
  5. ZZULIOJ.1108: 打印数字图形(函数专题)
  6. 谷歌浏览器切换黑色背景
  7. springboot junit测试时环境变量问题 idea
  8. 实验吧-让我进去【salt加密 哈希长度拓展攻击】
  9. 巨巨的磁盘(线段树)
  10. 编程网校课程python_如何看待风变编程的 Python 网课?