哈夫曼编译码器课程设计报告(完整版)
哈夫曼编码译码器---课程设计报告.docx
目录目⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯ (2)1 程的目的和意⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯32 需求分析⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯43 概要⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯4 4⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯.85 分析和果⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯.11 6⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯127致⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯138附⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯13参考文献⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯..201课程设计目的与意义在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。
哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。
哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。
树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“ 1”的序列作为和各个对应的字符的编码,这就是哈夫曼编码。
通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。
电报通信是传递文字的二进制码形式的字符串。
但在信息传递时,总希望总长度尽可能最短,即采用最短码。
作为计算机专业的学生,我们应该很好的掌握这门技术。
在课堂上,我们能过学到许多的理论知识,但我们很少有过自己动手实践的机会!课程设计就是为解决这个问题提供了一个平台。
在课程设计过程中,我们每个人选择一个课题,认真研究,根据课堂讲授内容,借助书本,自己动手实践。
这样不但有助于我们消化课堂所讲解的内容,还可以增强我们的独立思考能力和动手能力;通过编写实验代码和调试运行,我们可以逐步积累调试 C 程序的经验并逐渐培养我们的编程能力、用计算机解决实际问题的能力。
哈夫曼编_译码器数据结构课程设计报告
摘要;哈夫曼编码是根据字符的使用率的高低对字符进行不等长的编码,从而使使用率高的字符占用较少的空间,从而在传输的过程中大大提高了数据的空间传输效率。
本设计采用二叉链表的存储结构,建立哈夫曼树;用递归调用的方式对哈夫曼树的节点进行编码,生成与字符对应的哈夫曼编码。
本设计完全采用C++语言进行编程,并在XCode 6编译器上调试运行通过。
本程序使用中文界面,并有相应的提示信息,便于操作和程序运行。
关键词:哈夫曼树;哈夫曼编码;递归调用;二叉链表AbstractHuffman coding is based on the level of usage of characters ranging from long coding, so that high usage rate of the characters occupy less storage space , in the course of transmission has greatly enhanced the efficiency of data transmission space. This design build the Huffman tree by using Binary Tree storage structure, encoded Huffman tree nodes by recursive calling, and the characters generate the corresponding Huffman coding. The procedure completely write with C++ language and has Chinese explanatory note. What’s more, i t was debugged in XCode 6 debugger and run well. The whole procedure, with Chinese interface and the corresponding tips ,is convenient to run and easy to be operated.Keywords: Huffman Tree; Huffman code; Recursive call; Binary List目录摘要..................................................................................................................... 错误!未定义书签。
哈夫曼编译码器课程设计报告材料
《数据结构》课程设计报告题目: 哈夫曼编/译码器专业: 计算机科学与技术(对口) 班级:13(3) : 霞 指导教师: 飞 成绩:计算机学院 2015年11月12日2015-2016学年 第1学期目录1设计容及要求 (3)1.1 容 (3)1.2 要求 (3)2概要设计 (4)2.1抽象数据类型定义 (4)2.2模块划分 (4)3设计过程及代码 (5)3.1设计过程 (5)3.2代码 (7)4设计结果与分析 (10)5参考文献 (12)1设计容及要求1.1 容利用哈夫曼编码进行信息通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。
试为这样的信息收发站写一个哈夫曼编/译码系统。
1.2 要求一个完整的系统应具有以下功能:(1)I:初始化(Initialization)。
从终端读入字符集大小n,以及n个字符和n 个权值,建立哈夫曼树,并将它存于文件hfmTree中。
(2)E:编码(Encoding)。
利用已建好的哈夫曼树(如不在存,则从文件htmTree 中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
(3)D:译码(Decoding)。
利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。
(4)P:印代码文件(Print)。
将文件CodeFile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码写入文件CodePrint中。
(5)T:印哈夫曼树(Tree Printing)。
将已在存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。
[测试数据](1)数据一:已知某系统在通信联络中只可能出现8种字符,其概率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,以此设计哈夫曼编码。
哈夫曼编码译码课程设计报告
哈夫曼编码译码课程设计报告《数据结构》课程设计——赫夫曼编码/译码器设计指导教师:李文书、周维达班级:10电信实验班学号:Q10600132姓名:王彬彬一、实验目的1、提高分析问题、解决问题的能力,进一步巩固数据结构各种原理与方法。
2、熟悉掌握一门计算机语言,能够进行数据算法设计。
二、实验原理哈夫曼编\译码器的主要功能是先建立哈夫曼树,然后利用建好的哈夫曼树生成哈夫曼编码后进行译码。
在数据通信中,经常需要将传送的文字转换成由二进制字符0、1组成的二进制串,称之为编码。
构造一棵哈夫曼树,规定哈夫曼树中的左分之代表0,右分支代表1,则从根节点到每个叶子节点所经过的路径分支组成的0和1的序列便为该节点对应字符的编码,称之为哈夫曼编码。
最简单的二进制编码方式是等长编码。
若采用不等长编码,让出现频率高的字符具有较短的编码,让出现频率低的字符具有较长的编码,这样可能缩短传送电文的总长度。
哈夫曼树课用于构造使电文的编码总长最短的编码方案。
主要流程图如下:三、实验步骤1:写好流程图,设计实验方案。
2:初始化,从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件HuofumanTree中。
3:编码。
利用已建好的哈夫曼树,对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
4:译码。
利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件Textfile中。
5:印代码文件(Print).将文件CodeFile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件CodePrint中。
6:印哈夫曼树(Treeprinting).将已在内存中的哈夫曼树以直观的方式(比如树)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint 中。
具体函数如下:1:Initialization() 初始化2:Encoding() 编码3:Decoding() 译码4:Print_file() 打印代码文件5:search(k,j,p) 搜索二叉树6:Print_tree() 打印二叉树7:menu() 主菜单9:main() 主函数四、实验结果与分析(1)大致个人测试案例:主界面:。
哈夫曼编码译码器实验报告
哈夫曼编码译码器实验报告实验名称:哈夫曼编码译码器实验一、实验目的:1.了解哈夫曼编码的原理和应用。
2.实现一个哈夫曼编码的编码和译码器。
3.掌握哈夫曼编码的编码和译码过程。
二、实验原理:哈夫曼编码是一种常用的可变长度编码,用于将字符映射到二进制编码。
根据字符出现的频率,建立一个哈夫曼树,出现频率高的字符编码短,出现频率低的字符编码长。
编码过程中,根据已建立的哈夫曼树,将字符替换为对应的二进制编码。
译码过程中,根据已建立的哈夫曼树,将二进制编码替换为对应的字符。
三、实验步骤:1.构建一个哈夫曼树,根据字符出现的频率排序。
频率高的字符在左子树,频率低的字符在右子树。
2.根据建立的哈夫曼树,生成字符对应的编码表,包括字符和对应的二进制编码。
3.输入一个字符串,根据编码表将字符串编码为二进制序列。
4.输入一个二进制序列,根据编码表将二进制序列译码为字符串。
5.比较编码前后字符串的内容,确保译码正确性。
四、实验结果:1.构建哈夫曼树:-字符出现频率:A(2),B(5),C(1),D(3),E(1) -构建的哈夫曼树如下:12/\/\69/\/\3345/\/\/\/\ABCDE2.生成编码表:-A:00-B:01-C:100-D:101-E:1103.编码过程:4.译码过程:5.比较编码前后字符串的内容,结果正确。
五、实验总结:通过本次实验,我了解了哈夫曼编码的原理和应用,并且实现了一个简单的哈夫曼编码的编码和译码器。
在实验过程中,我充分运用了数据结构中的树的知识,构建了一个哈夫曼树,并生成了编码表。
通过编码和译码过程,我进一步巩固了对树的遍历和节点查找的理解。
实验结果表明,本次哈夫曼编码的编码和译码过程正确无误。
在实验的过程中,我发现哈夫曼编码对于频率较高的字符具有较短的编码,从而实现了对字符串的高效压缩。
同时,哈夫曼编码还可以应用于数据传输和存储中,提高数据的传输效率和存储空间的利用率。
通过本次实验,我不仅掌握了哈夫曼编码的编码和译码过程,还深入了解了其实现原理和应用场景,加深了对数据结构和算法的理解和应用能力。
HFM报告
课程设计报告题目:哈夫曼编/译码器班级:计算机四班24021004学号:2402100407姓名:周博完成日期:2011年6月10日一、设计题目哈夫曼编码/译码器二、需求分析Ⅰ、运行环境:Microsoft Visual C++Ⅱ、程序执行的命令包括1 初始化:输入一串字符(正文),计算不同字符(包括空格)的数目以及每种字符出现的频率(以该种字符出现的次数作为其出现频率),根据权值建立哈夫曼树,输出每一种字符的哈夫曼编码。
2 编码:利用求出的哈夫曼编码,对该正文(字符串)进行码,并输出。
3 译码:对于得到的一串编码,利用已求得的哈夫曼编码进行译码,将译出的正文输出。
4 结束三、设计目的:1. 掌握建立哈夫曼树和哈夫曼编码的方法。
2. 掌握哈夫曼编码的实际应用方法。
四、设计内容利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
这要求在发送端通过一个编码系统,对待传数据预先编码,在接收端将传来的数据进行译码。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编\译码系统。
试为这样的信息收发站写一个哈夫曼的编\译系统。
五设计说明:1 算法设计思想:确定哈夫曼树和哈夫曼编码的存储表示,在数组中存放结点的各类信息,设计构造哈夫曼树的程序creathuffmantree、求出n个字母的哈夫曼编码程序huffmancode和哈夫曼的译码程序huffmandecode。
利用译码程序进行译码并输出,main()中调用各个函数,实现整个过程。
2.二叉树的抽象数据类型定义为:ADT BinaryTree{数据对象D:D是具有相同特性的数据元素的集合数据关系R:若D为空,则BinaryTree称为空二叉树;若D不为空,则BinaryTree满足二元关系;基本操作P:InitBiTree(&T);操作结果:构造空二叉树T。
DestroyBiTree(&T);初始条件:二叉树存在操作结果:销毁二叉树CreatBiTree(&T,definition);操作结果:按definition构造二叉树ClearBiTree(&T);操作结果:将二叉树清空Value(T,e);初始条件:二叉树存在,e为树中某个结点.操作结果:返回e的值。
哈夫曼编译码器课程设计报告(完整版)
XXX学院本科数据结构课程设计总结报告设计题目:实验一、哈夫曼编/译码器学生:XXX系别:XXX专业:XXX班级:XXX学号:XXX指导教师:XXX XXX2012年6 月21日xxx学院课程设计任务书题目一、赫夫曼编译码器专业、班级xxx学号xxx xxx主要容、基本要求、主要参考资料等:1. 主要容利用哈夫曼编码进行信息通信可大大提高信道利用率,缩短信息传输时间,降低传输成本。
要求在发送端通过一个编码系统对待传数据预先编码;在接收端将传来的数据进行译码(复原)。
对于双工信道(既可以双向传输信息的信道),每端都需要一个完整的编/译码系统。
试为这样的信息收发站写一个哈夫曼的编/译码系统。
2. 基本要求系统应具有以下功能:(1)C:编码(Coding)。
对文件tobetrans中的正文进行编码,然后将结果存入文件codefile中,将以此建好的哈夫曼树存入文件HuffmanTree中(2)D:解码(Decoding)。
利用已建好的哈夫曼树将文件codefile中的代码进行译码,结果存入textfile中。
(3)P:打印代码文件(Print)。
将文件codefile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件codeprint中。
(4)T:打印哈夫曼树(Tree Printing)。
将已在存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件treeprint中。
3. 参考资料:数据结构(C语言版)严蔚敏、吴伟民编著;数据结构标准教程胡超、闫宝玉编著完成期限:2012年6月21 日指导教师签名:课程负责人签名:2012年 6月 21 日一、设计题目(任选其一)实验一、哈夫曼编/译码器二、实验目的1巩固和加深对数据结构的理解,提高综合运用本课程所学知识的能力;2 深化对算法课程中基本概念、理论和方法的理解;3 巩固构造赫夫曼树的算法;4 设计试验用程序实验赫夫曼树的构造。
哈夫曼编译码器课程设计报告
《数据结构》课程设计报告题目: 哈夫曼编/译码器 专业: 计算机科学与技术(对口)班级: 13(3) 姓名: 陈霞指导教师:彭飞2015-2016学年 第1学期成绩:计算机学院2015年11月12日目录1 设计内容及要求 (3)1.1 内容 (3)1.2 要求 (4)2 概要设计 (5)2.1 抽象数据类型定义 (5)2.2 模块划分 (6)3 设计过程及代码 (7)3.1 设计过程 (7)3.2 代码 (11)4 设计结果与分析 (17)5 参考文献 (20)1设计内容及要求1.1 内容利用哈夫曼编码进行信息通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。
试为这样的信息收发站写一个哈夫曼编/译码系统。
1.2 要求一个完整的系统应具有以下功能:(1)I:初始化(Initialization)。
从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。
(2)E:编码(Encoding)。
利用已建好的哈夫曼树(如不在内存,则从文件htmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
(3)D:译码(Decoding)。
利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。
(4)P:印代码文件(Print)。
将文件CodeFile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码写入文件CodePrint中。
(5)T:印哈夫曼树(Tree Printing)。
将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。
[测试数据](1)数据一:已知某系统在通信联络中只可能出现8种字符,其概率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,以此设计哈夫曼编码。
哈夫曼编码译码器---课程设计报告.docx
目录目⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯ (2)1 程的目的和意⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯32 需求分析⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯43 概要⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯4 4⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯.85 分析和果⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯.11 6⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯127致⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯138附⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯13参考文献⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯..201课程设计目的与意义在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。
哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。
哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。
树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“ 1”的序列作为和各个对应的字符的编码,这就是哈夫曼编码。
通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。
电报通信是传递文字的二进制码形式的字符串。
但在信息传递时,总希望总长度尽可能最短,即采用最短码。
作为计算机专业的学生,我们应该很好的掌握这门技术。
在课堂上,我们能过学到许多的理论知识,但我们很少有过自己动手实践的机会!课程设计就是为解决这个问题提供了一个平台。
在课程设计过程中,我们每个人选择一个课题,认真研究,根据课堂讲授内容,借助书本,自己动手实践。
这样不但有助于我们消化课堂所讲解的内容,还可以增强我们的独立思考能力和动手能力;通过编写实验代码和调试运行,我们可以逐步积累调试 C 程序的经验并逐渐培养我们的编程能力、用计算机解决实际问题的能力。
哈夫曼编码译码器实验报告
问题解析与解题方法问题分析:设计一个哈夫曼编码、译码系统。
对一个ASCII编码的文本文件中的字符进行哈夫曼编码,生成编码文件;反过来,可将编码文件译码还原为一个文本文件。
(1)从文件中读入任意一篇英文短文(文件为ASCII编码,扩展名为txt);(2)统计并输出不同字符在文章中出现的频率(空格、换行、标点等也按字符处理);(3)根据字符频率构造哈夫曼树,并给出每个字符的哈夫曼编码;(4)将文本文件利用哈夫曼树进行编码,存储成压缩文件(编码文件后缀名.huf)(5)用哈夫曼编码来存储文件,并和输入文本文件大小进行比较,计算文件压缩率;(6)进行译码,将huf文件译码为ASCII编码的txt文件,与原txt文件进行比较。
根据上述过程可以知道该编码译码器的关键在于字符统计和哈夫曼树的创建以及解码。
哈夫曼树的理论创建过程如下:一、构成初始集合对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F={T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。
二、选取左右子树在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。
三、删除左右子树从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。
四、重复二和三两步,重复二和三两步,直到集合F中只有一棵二叉树为止。
因此,有如下分析:1.我们需要一个功能函数对ASCII码的初始化并需要一个数组来保存它们;2.定义代表森林的数组,在创建哈夫曼树的过程当中保存被选中的字符,即给定报文中出现的字符,模拟哈夫曼树选取和删除左右子树的过程;3.自底而上地创建哈夫曼树,保存根的地址和每个叶节点的地址,即字符的地址,然后自底而上检索,首尾对换调整为哈夫曼树实现哈弗曼编码;4.从哈弗曼编码文件当中读入字符,根据当前字符为0或者1的状况访问左子树或者右孩子,实现解码;5.使用文件读写操作哈夫曼编码和解码结果的写入;解题方法:结构体、数组、类的定义:1.定义结构体类型的signode 作为哈夫曼树的节点,定义结构体类型的hufnode 作为哈夫曼编码对照表的节点,定义HFM类实现对哈夫曼树的创建,利用其成员函数完成哈夫曼编码译码的工作。
哈夫曼编译码器课程设计报告完整版
哈夫曼编译码器课程设计报告完整版XXX学院本科数据结构课程设计总结报告设计题目:实验一、哈夫曼编/译码器学生姓名:XXX系别:XXX专业:XXX班级:XXX学号:XXX指导教师:XXX XXX6 月 21日xxx学院课程设计任务书题目一、赫夫曼编译码器专业、班级 xxx学号 xxx 姓名 xxx主要内容、基本要求、主要参考资料等:1. 主要内容利用哈夫曼编码进行信息通信可大大提高信道利用率,缩短信息传输时间,降低传输成本。
要求在发送端经过一个编码系统对待传数据预先编码;在接收端将传来的数据进行译码(复原)。
对于双工信道(既能够双向传输信息的信道),每端都需要一个完整的编/译码系统。
试为这样的信息收发站写一个哈夫曼的编/译码系统。
2. 基本要求系统应具有以下功能:(1)C:编码(Coding)。
对文件tobetrans中的正文进行编码,然后将结果存入文件codefile中,将以此建好的哈夫曼树存入文件HuffmanTree中(2)D:解码(Decoding)。
利用已建好的哈夫曼树将文件codefile中的代码进行译码,结果存入textfile中。
(3)P:打印代码文件(Print)。
将文件codefile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件codeprint中。
(4)T:打印哈夫曼树(Tree Printing)。
将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件treeprint中。
3. 参考资料:数据结构(C语言版)严蔚敏、吴伟民编著;数据结构标准教程胡超、闫宝玉编著完成期限: 6月21 日指导教师签名:课程负责人签名:6月 21 日一、设计题目(任选其一)实验一、哈夫曼编/译码器二、实验目的1巩固和加深对数据结构的理解,提高综合运用本课程所学知识的能力;2 深化对算法课程中基本概念、理论和方法的理解;3 巩固构造赫夫曼树的算法;4 设计试验用程序实验赫夫曼树的构造。
赫夫曼编译码器课程设计报告
数据结构课程设计报告书题目名称赫夫曼编/译码器学院专业专业班级学号学生姓名指导教师目录一需求分析 (1)二概要设计 (1)1 抽象数据类型2 算法设计的思想3 程序整体及要紧算法的流程图三源代码 (4)四测试结果 (12)五运行结果分析 (14)六收成、体会及意见 (14)一、需求分析1.演示进程中,输入字符为26个大写的英文字母与空格,输入个数n<=27,输入形式以一个“#”为终止符,且不可输入非法字符和重复自符,假设显现,程序将自动删除。
2.程序执行的命令包括:1)依照给出的数值构造哈夫曼树。
2)依照哈夫曼树给字符编码。
3)依照所得出的编码进行译码。
3.利用哈夫曼编码进行通信能够大大提高信道利用率,缩短信息传输时刻,降低传输本钱。
在此程序的运行进程中,充分表现出赫夫曼编译码器可利用价值。
二、概要设计为了实现上述程序功能,需要一个抽象数据类型,如:1.抽象数据类型赫夫曼树的概念如下:ADT HuffmanTree{数据对象D:D是具有相同特性的数据元素的集合。
数据关系R:假设D=Φ,那么R=Φ,称HuffmanTree为空二叉树;假设D≠Φ,那么R={H},H是如下二元关系:(1)在D中存在唯一的称为根的数据元素root,它在关系H下无前驱;(2)假设D-{root}≠Φ,那么存在D-{root}={ D1,Dr},且D1⋂Dr=Φ;(3)假设D1≠Φ,那么D1中存在唯一的元素x1,<root,x1>∈H,且存在D1上的关系H1⊂H;假设Dr≠Φ,那么Dr中存在唯一的元素xr,<root,xr>∈H,且存在Dr上的关系Hr⊂H;H={<root,x1>,<root,xr>,H1,Hr}(4)(D1,{H1})是一棵符合本概念的二叉树,称为根的左子树,(Dr,{Hr})是一棵符合本概念的二叉树,称为根的右子树。
二、算法的设计思想此程序的设计思想为:输入程序所需数据,构建相应的赫夫曼树,利用已有数据进行赫夫曼编码,并进行译码进程,最后对运行结果分析处置。
数据结构课程设计哈夫曼编码译码器
题目一: 哈夫曼编码与译码一、任务设计一个运用哈夫曼算法的编码和译码系统, 反复地显示并解决以下项目, 直到选择退出为止。
规定:1) 将权值数据存放在数据文献(文献名为data.txt, 位于执行程序的当前目录中) ;2) 初始化:键盘输入字符集记录字符权值、自定义26个字符和26个权值、记录文献中一篇英文文章中26个字母, 建立哈夫曼树;3) 编码: 运用建好的哈夫曼树生成哈夫曼编码;4) 输出编码(一方面实现屏幕输出, 然后实现文献输出);5)译码(键盘接受编码进行译码、文献读入编码进行译码);6) 界面优化设计。
二、流程图三、代码分解 //头文献 #include<stdio.h> #include<string.h> #include<stdlib.h> #include <conio.h> #define N 1000 #define M 2*N-1 #define MAXcode 6000 //函数声明void count(CHar &ch,HTNode ht[]);void editHCode(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]); //编码函数void printyima(HTNode ht[],HCode hcd[],int n,char bianma[]); //译码函数 void creatHT(HTNode ht[],int n);字符集记录符集记录权值 权值 至文献“哈夫曼树。
t xt” 菜单1.从键盘输入字符集进行编码2.从文献读入字符集进行编码1.从键盘输入编码进行译码2.从文献读入编码进行译码0.返回上级菜单 0.返回上级菜单void CreateHCode (HTNode ht[],HCode hcd[],int n);void DispHCode(HTNode ht[],HCode hcd[],int n);void input_key(CHar &ch);void input_file(CHar &ch);void input_cw(HTNode ht[]);void bianma1(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]); void bianma2(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]); void yima1(HTNode ht[],HCode hcd[],int n,char bianma[]);void yima2(HTNode ht[],HCode hcd[],int n,char bianma[]);void creat_cw();void bianmacaidan();void yimacaidan();void bianmayima();int caidan();//结构体typedef struct{char data;int parent;int weight;int lchild;int rchild;}HTNode;typedef struct{char cd[N];int start;}HCode;typedef struct{char s[N];int num;}CHar;CHar ch;HTNode ht[M];HCode hcd[N];//主函数int main(){int xh;while(1){system("color 1f"); //操作菜单背景颜色 xh=caidan(); //调用菜单函数switch(xh) //switch语句 {case 1:system("cls");creat_cw();break;case 2:system("cls");creatHT(ht,n);break;case 3:system("cls");CreateHCode(ht,hcd,n);DispHCode(ht,hcd,n);break;case 4:system("cls");bianmayima();break;case 0:system("cls");printf("\n\n\n\n\n\n\n\n\n\t\t\t\t感谢使用本系统!\n\n\n\n\n\n\n \t\t\t");exit(0);default:system("cls");putchar('\a');printf("\n\t\t输入有误, 请重新输入:\n");break;}}return 0;}//菜单函数int caidan() //菜单函数模块//{int xh;printf("\n\n\n");printf("\t\t 欢迎使用哈夫曼编码译码系统\n");printf("\t\t \n");printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");printf("\t\t*= =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n");printf("\t\t*= 1.建立字符权值=*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n"); printf("\t\t*= 2.建立并输出哈夫曼树=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n"); printf("\t\t*= 3.生成并查看哈夫曼编码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n"); printf("\t\t*= 4.编码与译码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n"); printf("\t\t*= 0.退出系统=*\n"); printf("\t\t*= =*\n"); printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n"); printf("\n\t\t请输入序号进行选择:");scanf("%d", &xh);return xh; //返回从键盘接受的选项}void bianmayima(){int xh;while(1){printf("\n\n\n\n\n");printf("\t\t 编码与译码\n"); printf("\t\t \n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\t\t*= 1.编码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 2.译码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 0.返回上级菜单=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh);switch(xh) //switch语句{case 1:system("cls");bianmacaidan();break;case 2:system("cls");yimacaidan();break;case 0:system("cls");return;default:system("cls");putchar('\a');printf("\n\t\t输入有误, 请重新输入:\n");break;}}}void yimacaidan(){int xh;while(1){printf("\n\n\n\n\n");printf("\t\t 译码\n"); printf("\t\t \n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 1.键盘输入编码进行译码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 2.文献读入编码进行译码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 0.返回上级菜单=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh);switch(xh) //switch语句{case 1:system("cls");yima1(ht,hcd,n,bianma);break;case 2:system("cls");yima2(ht,hcd,n,bianma);break;case 0:system("cls");return;default:system("cls");putchar('\a');printf("\n\t\t输入有误, 请重新输入:\n");break;}}}void bianmacaidan(){int xh;while(1){printf("\n\n\n\n\n");printf("\t\t 编码\n"); printf("\t\t \n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 1.键盘输入字符集编码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 2.文献读入文章编码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 0.返回上级菜单=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh);switch(xh) //switch语句{case 1:system("cls");bianma1(ht,hcd,ch,n,bianma);break;case 2:system("cls");bianma2(ht,hcd,ch,n,bianma);break;case 0:system("cls");return;default:system("cls");putchar('\a');printf("\n\t\t输入有误, 请重新输入:\n");break;}}}void creat_cw(){int xh2;while(1){printf("\n\n\n\n\n");printf("\t\t 建立字符权值\n"); printf("\t\t \n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 1.从键盘输入字符集进行记录=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 2.从文献读入字符集记录=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 3.自定义字符权值=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 0.返回上级菜单=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh2);switch(xh2) //switch语句{case 1:system("cls");input_key(ch);break;case 2:system("cls");input_file(ch);break;case 3:system("cls");input_cw(ht);break;case 0:system("cls");return;default:system("cls");putchar('\a');printf("\n\t\t输入有误, 请重新输入:\n");break;}}}//建立字符权值模块void input_key(CHar &ch){int i,j=0;char st[N];printf("请输入字符集(以‘#’结束):\n");for(i=0;i<N;i++){scanf("%c",&st[i]);if(st[i]=='#'){st[i]='\0';break;}}strcpy(ch.s,st);count(ch,ht);printf("按任意键返回!");getch();system("cls");return;}void input_file(CHar &ch){int i;FILE*fp;char filename[20];printf("请输入要打开的文献名(*.txt):");scanf("%s",&filename);if((fp=fopen(filename,"r"))==NULL){printf("\n\t\t文献打开失败");return;}for(i=0;!feof(fp);i++){fread(&ch.s[i],sizeof(char),1,fp);}printf("读入成功!\n");printf("文献中的字符集为:%s\n",ch.s);fclose(fp);count(ch,ht);printf("按任意键返回!");getch();system("cls");return;}void input_cw(HTNode ht[]){int i,w,s,j;char a;printf("要输入的字符总个数是?:");scanf("%d",&s);n=s;printf("请输入字符及其权值:\n");for(i=0;i<s;i++){printf("请输入第%d个字母:",i+1);scanf("%s",&a);ht[i].data=a;printf("请输入其权值:");scanf("%d",&w);ht[i].weight=w;}FILE *fp;if((fp=fopen("data.txt","w"))==0){printf("\n\t\t文献打开失败");return;}printf("\n定义权值成功!\n\n");printf("各字符及其权值为:\n\n");fprintf(fp,"各字符及其权值为:\n");printf(" 字符\t权值");fprintf(fp," 字符\t权值");for(j=0;j<i;j++){ printf("\n");fprintf(fp,"\n");printf(" %-8c%-8d",ht[j].data,ht[j].weight);fprintf(fp," %-8c%-8d%",ht[j].data,ht[j].weight); }printf("\n");printf("\n字符权值已输出至文献“data.txt”!");fclose(fp);printf("输入完毕, 按任意键返回!");getch();system("cls");return;}//记录字符权值函数void count(CHar &ch,HTNode ht[]){int i,j,m=0;char c[N];int sum[N]={0};for(i=0;ch.s[i]!='\0';i++){for(j=0;j<m;j++)if(ch.s[i]==c[j]||(c[j]>='a'&&c[j]<='z'&&ch.s[i]+32==c[j])) break;if(j<m)sum[j]++;else{if(ch.s[i]>='A'&&ch.s[i]<='Z')c[j]=ch.s[i]+32;else c[j]=ch.s[i];sum[j]++;m++;}}for(i=0;i<m;i++){ht[i].data=c[i];ht[i].weight=sum[i];}n=m;FILE *fp;if((fp=fopen("data.txt","w"))==0) {printf("\n\t\t文献打开失败"); return;}printf("\n记录权值成功!\n\n"); printf("各字符及其权值为:\n\n"); fprintf(fp,"各字符及其权值为:\n"); printf(" 字符\t权值");fprintf(fp," 字符\t权值");for(j=0;j<m;j++){ printf("\n");fprintf(fp,"\n");printf(" %-8c%-8d",ht[j].data,ht[j].weight);fprintf(fp," %-8c%-8d%",ht[j].data,ht[j].weight);}printf("\n");printf("\n字符权值已输出至文献“data.txt”!");fclose(fp);}//构造哈夫曼树void creatHT(HTNode ht[],int n){FILE *fp;if((fp=fopen("哈夫曼树.txt","w"))==0){printf("\n\t\t文献打开失败");return;}int i,j,k,lnode,rnode;int min1,min2;for (i=0;i<2*n-1;i++)ht[i].parent=ht[i].lchild=ht[i].rchild=-1;for (i=n;i<2*n-1;i++){min1=min2=32767;lnode=rnode=-1;for(k=0;k<=i-1;k++)if(ht[k].parent==-1){if (ht[k].weight<min1){min2=min1;rnode=lnode;min1=ht[k].weight;lnode=k;}else if(ht[k].weight<min2){min2=ht[k].weight;rnode=k;}}ht[lnode].parent=i;ht[rnode].parent=i;ht[i].weight=ht[lnode].weight+ht[rnode].weight;ht[i].lchild=lnode;ht[i].rchild=rnode;}printf("建立huffman树成功!\n");printf("输出huffman树:\n");fprintf(fp,"输出huffman树:\n");printf("\t字符\t权值\t父节点\t 左子节点\t右子节点");fprintf(fp,"\t字符\t权值\t父节点\t 左子节点\t右子节点");for(j=1;j<i;j++){ printf("\n");fprintf(fp,"\n");printf("\t %-8c%-8d%-10d%-14d%-10d",ht[j].data,ht[j].weight,ht[j].parent,ht[i]. lchild,ht[j].rchild);fprintf(fp,"\t %-8c%-8d%-10d%-14d%-10d",ht[j].data,ht[j].weight,ht[j].parent,h t[i].lchild,ht[j].rchild);}printf("\n");printf("哈夫曼树已输出至文献“哈夫曼树.txt”!按任意键返回!");fclose(fp);getch();system("cls");return;}//生成哈夫曼编码void CreateHCode (HTNode ht[],HCode hcd[],int n){int i,f,c,j=0;HCode hc;for(i=0;i<n;i++){hc.start=n;c=i;hc.cd[hc.start--]='0';f=ht[i].parent;while(f!=-1){if (ht[f].lchild==c)hc.cd[hc.start--]='0';elsehc.cd[hc.start--]='1';c=f;f=ht[f].parent;}hc.start++;for(j=0;j<hc.start;j++)hc.cd[j]=' ';hcd[i]=hc;}}void DispHCode(HTNode ht[],HCode hcd[],int n) {FILE *fp;if((fp=fopen("哈夫曼编码.txt","w"))==0){printf("\n\t\t文献打开失败");return;}int i,k;int sum=0,m=0,j;printf("输出字符哈夫曼编码:\n"); fputs("输出字符哈夫曼编码:\n",fp); for (i=0;i<n;i++){j=0;printf("%c:\t",ht[i].data);fprintf(fp,"\n%c:\t",ht[i].data);for (k=hcd[i].start;k<=n;k++){printf("%c",hcd[i].cd[k]);j++;fprintf(fp,"%c",hcd[i].cd[k]); }m+=ht[i].weight;sum+=ht[i].weight*j;printf("\n");}printf("\n哈夫曼编码已保存至文献“哈夫曼编码.txt!按任意键返回!”");fclose(fp);getch();system("cls");}//编码函数void bianma1(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]){int i;char str[N];printf("请输入要编码的字符集(以‘#’结束):\n");for(i=0;i<N;i++){scanf("%c",&str[i]);if(str[i]=='#'){str[i]='\0';break;}}strcpy(ch.s,str);ch.num=strlen(str);editHCode(ht,hcd,ch,n,bianma);getch();system("cls");}void bianma2(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]) {int i;FILE*fp;char filename[20];printf("请输入要打开的文献名(*.txt):");scanf("%s",&filename);if((fp=fopen(filename,"r"))==NULL){printf("\n\t\t文献打开失败");return;}for(i=0;!feof(fp);i++){fread(&ch.s[i],sizeof(char),1,fp);}ch.num=strlen(ch.s);printf("\n读入成功!\n");printf("文献中的字符集为:\n%s",ch.s);fclose(fp);editHCode(ht,hcd,ch,n,bianma);system("cls");return;}//译码函数void yima1(HTNode ht[],HCode hcd[],int n,char bianma[]) {int i;char code[MAXcode];printf("请输入编码进行译码(以‘#’结束):\n");for(i=0;i<MAXcode;i++){scanf("%c",&code[i]);if(code[i]=='#'){code[i]='\0';break;}}strcpy(bianma,code);printyima(ht,hcd,n,bianma);printf("\n译码完毕!按任意键返回!");getch();system("cls");return;}void yima2(HTNode ht[],HCode hcd[],int n,char bianma[]) {int i;FILE*fp;char filename[20];printf("请输入要打开的文献名(*.txt):");scanf("%s",&filename);if((fp=fopen(filename,"r"))==NULL){printf("\n\t\t文献打开失败");return;}for(i=0;!feof(fp);i++){fread(&bianma[i],sizeof(char),1,fp);}printf("读入成功!\n");printf("文献中的编码是:%s\n",bianma);printyima(ht,hcd,n,bianma);printf("\n译码完毕!按任意键返回!");getch();system("cls");}四、调试结果主菜单建立字符权值选择2.从文献读入字符进行记录输入测试文献名“cs.txt”输出个字符权值建立哈夫曼树并输出至文献生成哈夫曼编码并保存至文献编码选择2.从文献读入字符集编码编码结果保存至文献译码选择2.从文献读入编码, 读入上一步的编码译码完毕, 返回!退出系统。
(完整word版)数据结构课程设计哈夫曼编码111
《数据结构与算法》课程设计(2009/2010学年第二学期第20周)指导教师:班级:计算机科学与技术学号:姓名:《数据结构与算法》课程设计目录一、前言1.摘要2.《数据结构与算法》课程设计任务书二、实验目的三、题目--赫夫曼编码/译码器1.问题描述2.基本要求3.测试要求4.实现提示四、需求分析--具体要求五、概要设计六、程序说明七、详细设计八、实验心得与体会前言1.摘要随着计算机的普遍应用与日益发展,其应用早已不局限于简单的数值运算,而涉及到问题的分析、数据结构框架的设计以及设计最短路线等复杂的非数值处理和操作。
算法与数据结构的学习就是为以后利用计算机资源高效地开发非数值处理的计算机程序打下坚实的理论、方法和技术基础。
算法与数据结构旨在分析研究计算机加工的数据对象的特性,以便选择适当的数据结构和存储结构,从而使建立在其上的解决问题的算法达到最优。
数据结构是在整个计算机科学与技术领域上广泛被使用的术语。
它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。
数据结构有逻辑上的数据结构和物理上的数据结构之分。
逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安排。
数据结构是数据存在的形式。
《数据结构》主要介绍一些最常用的数据结构,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。
数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。
学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。
通过课程设计可以提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。
2.《数据结构与算法》课程设计任务书《数据结构与算法》是计算机专业重要的核心课程之一,在计算机专业的学习过程中占有非常重要的地位。
数据结构课程设计哈夫曼编码译码器
题目一:哈夫曼编码与译码一、任务设计一个利用哈夫曼算法的编码和译码系统,重复地显示并处理以下项目,直到选择退出为止。
要求:1) 将权值数据存放在数据文件(文件名为,位于执行程序的当前目录中) ;2) 初始化:键盘输入字符集统计字符权值、自定义26个字符和26个权值、统计文件中一篇英文文章中26个字母,建立哈夫曼树;3) 编码:利用建好的哈夫曼树生成哈夫曼编码;4) 输出编码(首先实现屏幕输出,然后实现文件输出);5)译码(键盘接收编码进行译码、文件读入编码进行译码);6) 界面优化设计。
二、流程图主菜单1.建立字符权值2.建立并输出哈夫曼树3.建立并查看哈弗曼编4.编码与译码0.退出系统1.从键盘输入字符集统1.编码2.译码0.返回上级菜单三、代码分解立字符权值 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n");printf("\t\t*= 2.建立并输出哈夫曼树 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n");printf("\t\t*= 3.生成并查看哈夫曼编码 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n");printf("\t\t*= 4.编码与译码 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n");printf("\t\t*= 0.退出系统 =*\n");printf("\t\t*= =*\n");printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");printf("\n\t\t请输入序号进行选择:");scanf("%d", &xh);return xh; 码 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\t\t*= 2.译码 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\t\t*= 0.返回上级菜单 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh);switch(xh) 盘输入编码进行译码=*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\t\t*= 2.文件读入编码进行译码 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\t\t*= 0.返回上级菜单 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh);switch(xh) 盘输入字符集编码 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\t\t*= 2.文件读入文章编码 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\t\t*= 0.返回上级菜单 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh);switch(xh) 键盘输入字符集进行统计=*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\t\t*= 2.从文件读入字符集统计 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\t\t*= 3.自定义字符权值 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\t\t*= 0.返回上级菜单 =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh2);switch(xh2) xt):");scanf("%s",&filename);if((fp=fopen(filename,"r"))==NULL){printf("\n\t\t文件打开失败!!!");return;}for(i=0;!feof(fp);i++){fread(&[i],sizeof(char),1,fp);}=strlen;printf("读入成功!\n");printf("文件中的字符集为:%s\n",;fclose(fp);count(ch,ht);printf("按任意键返回!");getch();system("cls");return;}void input_cw(HTNode ht[]){int i,w,s,j;char a;printf("要输入的字符总个数是:");scanf("%d",&s);n=s;printf("请输入字符及其权值:\n");for(i=0;i<s;i++){printf("请输入第%d个字母:",i+1);scanf("%s",&a);ht[i].data=a;printf("请输入其权值:");scanf("%d",&w);ht[i].weight=w;}FILE *fp;if((fp=fopen("","w"))==0){printf("\n\t\t文件打开失败!!!");return;}printf("\n定义权值成功!\n\n");printf("各字符及其权值为:\n\n");fprintf(fp,"各字符及其权值为:\n");printf(" 字符\t权值");fprintf(fp," 字符\t权值");for(j=0;j<i;j++){ printf("\n");fprintf(fp,"\n");printf(" %-8c%-8d",ht[j].data,ht[j].weight);fprintf(fp," %-8c%-8d%",ht[j].data,ht[j].weight);}printf("\n");printf("\n字符权值已输出至文件“”!");fclose(fp);printf("输入完成,按任意键返回!");getch();system("cls");return;}ata=c[i];ht[i].weight=sum[i];}n=m;FILE *fp;if((fp=fopen("","w"))==0){printf("\n\t\t文件打开失败!!!");return;}printf("\n统计权值成功!\n\n");printf("各字符及其权值为:\n\n");fprintf(fp,"各字符及其权值为:\n");printf(" 字符\t权值");fprintf(fp," 字符\t权值");for(j=0;j<m;j++){ printf("\n");fprintf(fp,"\n");printf(" %-8c%-8d",ht[j].data,ht[j].weight);fprintf(fp," %-8c%-8d%",ht[j].data,ht[j].weight);}printf("\n");printf("\n字符权值已输出至文件“”!");fclose(fp);}xt","w"))==0){printf("\n\t\t文件打开失败!!!");return;}int i,j,k,lnode,rnode;int min1,min2;for (i=0;i<2*n-1;i++)ht[i].parent=ht[i].lchild=ht[i].rchild=-1;for (i=n;i<2*n-1;i++){min1=min2=32767;lnode=rnode=-1;for(k=0;k<=i-1;k++)if(ht[k].parent==-1){if (ht[k].weight<min1){min2=min1;rnode=lnode;min1=ht[k].weight;lnode=k;}else if(ht[k].weight<min2){min2=ht[k].weight;rnode=k;}}ht[lnode].parent=i;ht[rnode].parent=i;ht[i].weight=ht[lnode].weight+ht[rnode].weight;ht[i].lchild=lnode;ht[i].rchild=rnode;}printf("建立huffman树成功!\n");printf("输出huffman树:\n");fprintf(fp,"输出huffman树:\n");printf("\t字符\t权值\t父节点\t 左子节点\t右子节点");fprintf(fp,"\t字符\t权值\t父节点\t 左子节点\t右子节点");for(j=1;j<i;j++){ printf("\n");fprintf(fp,"\n");printf("\t %-8c%-8d%-10d%-14d%-10d",ht[j].data,ht[j].weight,ht[j] .parent,ht[i].lchild,ht[j].rchild);fprintf(fp,"\t %-8c%-8d%-10d%-14d%-10d",ht[j].data,ht[j].weight,h t[j].parent,ht[i].lchild,ht[j].rchild);}printf("\n");printf("哈夫曼树已输出至文件“哈夫曼树.txt”!按任意键返回!");fclose(fp);getch();system("cls");return;}arent;while(f!=-1){if (ht[f].lchild==c)[]='0';else[]='1';c=f;f=ht[f].parent;}++;for(j=0;j<;j++)[j]=' ';hcd[i]=hc;}}void DispHCode(HTNode ht[],HCode hcd[],int n){FILE *fp;if((fp=fopen("哈夫曼编码.txt","w"))==0){printf("\n\t\t文件打开失败!!!");return;}int i,k;int sum=0,m=0,j;printf("输出字符哈夫曼编码:\n");fputs("输出字符哈夫曼编码:\n",fp);for (i=0;i<n;i++){j=0;printf("%c:\t",ht[i].data);fprintf(fp,"\n%c:\t",ht[i].data);for (k=hcd[i].start;k<=n;k++){printf("%c",hcd[i].cd[k]);j++;fprintf(fp,"%c",hcd[i].cd[k]);}m+=ht[i].weight;sum+=ht[i].weight*j;printf("\n");}printf("\n哈夫曼编码已保存至文件“哈夫曼编码.txt!按任意键返回!”");fclose(fp);getch();system("cls");}xt):");scanf("%s",&filename);if((fp=fopen(filename,"r"))==NULL){printf("\n\t\t文件打开失败!!!");return;}for(i=0;!feof(fp);i++){fread(&[i],sizeof(char),1,fp);}=strlen;printf("\n读入成功!\n");printf("文件中的字符集为:\n%s",;fclose(fp);editHCode(ht,hcd,ch,n,bianma);getch();system("cls");return;}xt):");scanf("%s",&filename);if((fp=fopen(filename,"r"))==NULL){printf("\n\t\t文件打开失败!!!");return;}for(i=0;!feof(fp);i++){fread(&bianma[i],sizeof(char),1,fp);}printf("读入成功!\n");printf("文件中的编码是:%s\n",bianma);printyima(ht,hcd,n,bianma);printf("\n译码完成!按任意键返回!");getch();system("cls");}四、调试结果主菜单建立字符权值选择2.从文件读入字符进行统计输入测试文件名“”输出个字符权值建立哈夫曼树并输出至文件生成哈夫曼编码并保存至文件编码选择2.从文件读入字符集编码编码结果保存至文件译码选择2.从文件读入编码,读入上一步的编码译码完成,返回!退出系统。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
XXX学院本科数据结构课程设计总结报告设计题目:实验一、哈夫曼编/ 译码器学生:系XXX 别:XXX专业:XXX班级:XXX学号:XXX指导教师:XXX XXX2012 年 6 月21 日xxx 学院课程设计任务书题目一、赫夫曼编译码器专业、班级xxx学号xxx xxx 主要容、基本要求、主要参考资料等:1. 主要容利用哈夫曼编码进行信息通信可大大提高信道利用率,缩短信息传输时间,降低传输成本。
要求在发送端通过一个编码系统对待传数据预先编码;在接收端将传来的数据进行译码(复原)。
对于双工信道(既可以双向传输信息的信道),每端都需要一个完整的编/ 译码系统。
试为这样的信息收发站写一个哈夫曼的编/ 译码系统。
2. 基本要求系统应具有以下功能:(1)C:编码(Coding)。
对文件tobetrans 中的正文进行编码,然后将结果存入文件codefile 中,将以此建好的哈夫曼树存入文件HuffmanTree 中(2)D:解码(Decoding )。
利用已建好的哈夫曼树将文件codefile 中的代码进行译码,结果存入textfile 中。
(3)P:打印代码文件(Print )。
将文件codefile 以紧凑格式显示在终端上,每行50 个代码。
同时将此字符形式的编码文件写入文件codeprint 中。
(4)T:打印哈夫曼树(Tree Printing )。
将已在存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件treeprint 中。
3. 参考资料:数据结构(C 语言版)严蔚敏、吴伟民编著;数据结构标准教程胡超、闫宝玉编著完成期限:2012 年6 月21 日指导教师签名:课程负责人签名:、设计题目(任选其一)实验一、哈夫曼编/ 译码器二、实验目的1 巩固和加深对数据结构的理解,提高综合运用本课程所学知识的能力;2 深化对算法课程中基本概念、理论和方法的理解;3 巩固构造赫夫曼树的算法;2012 年 6 月21 日4 设计试验用程序实验赫夫曼树的构造。
三、运行环境(软、硬件环境)Windows xp sp3 ,Visual C++ 6.0 英文版四、算法设计的思想(1 )初始化赫夫曼树,输入文件tobetrans.txt 中各字符及其权值,并保存于hfmtree.txt 文件中(2)编码(Coding)。
对文件tobetrans中的正文进行编码,然后将结果存入文件codefile 中(3)D:解码(Decoding)。
利用已建好的哈夫曼树将文件codefile 中的代码进行译码,结果存入textfile 中。
(4)P:打印代码文件(Print)。
将文件codefile 以紧凑格式显示在终端上,每行50 个代码。
同时将此字符形式的编码文件写入文件codeprint 中。
(5)T:打印哈夫曼树(Tree Printing)。
将已在存中的哈夫曼树以直观的方式显示在终端上,同时将此字符形式的哈夫曼树写入文件treeprint 中。
五、流程图六、算法设计分析1. 赫夫曼树节点的数据类型定义为:typedef struct{ // 赫夫曼树的结构体char ch;int weight; // 权值int parent,lchild,rchild;} HTNode,*HuffmanTree;2. void HuffmanCoding(HuffmanTree &,char *,int *,int); 建立赫夫曼树的算法,此函数块调用了Select ()函数。
void select(HuffmanTree HT,int j,int *x,int *y); 从已建好的赫夫曼树中选择parent 为0,weight 最小的两个结点。
3.利用已建好的哈夫曼树从文件hfmtree.txt 中读入,对文件中的正文进行编码,然后将结果存入文件codefile.txt 中。
4. coding编码功能:对输入字符进行编码5. Decoding译码功能:利用已建好的哈夫曼树将文件codefile.txt 中的代码进行译码,结果存入文件textfile.txt 中。
6. Print() 打印功能函数:输出哈夫曼树以及对应的编码//////////////////////////////////////////////////////////////////////////////////////////#include <stdio.h>#include <stdlib.h>#include <string.h>// 定义赫夫曼树结点的结构体typedef struct{char ch; // 增加一个域,存放该节点的字符int weight;int parent,lchild,rchild; }HTNode,*HuffmanTree; typedef char **HuffmanCode; //指向赫夫曼编码的指针void tips(); // 打印操作选择界面void HuffmanCoding(HuffmanTree &,char *,int *,int); // 曼树的算法void select(HuffmanTree HT,int j,int *x,int *y); // 赫夫曼树中选择parent 为0,weight 最小的两个结点void Init();void Coding(); // void Decoding(); // void Print_code(); // void Print_tree(); // 编码译码打印译码好的代码打印哈夫曼树int Read_tree(HuffmanTree &); // 从文件中读入赫夫曼树voidfind(HuffmanTree &HT,char *code,char *text,int i,int m); // 译码时根据01 字符串寻找相应叶子节点的递归算法voidConvert_tree(unsigned char T[100][100],int s,int *i,int j); // 将存中的赫夫曼树转换成凹凸表形式的赫夫曼树HuffmanTree HT; // 全局变量int n=0; // 全局变量,存放赫夫曼树叶子结点的数目建立赫夫从已建好的{char select;while(1){tips();scanf("%c",&select);switch(select) // 选择操作,根据不同的序号选择不同的操作{case '1':Init();break;case '2':Coding();break;case '3':Decoding();break;case '4':Print_code();break;case '5':Print_tree();break;case '0':exit(1);default :printf("Input error!\n");}getchar();}return 0;}void tips() // 操作选择界面{printf(" ----------- ---------------------------------------- \n");printf(" -- 请选择操作--\n"); printf(" ----------- ------------------- \n");printf("\n");printf(" ----------- ------------ 1初始化赫夫曼树-- ------------ \n" )printf(" ----------- ------------ 2编码---------------------- ---- \n");printf(" ----------- ------------ 3译码---------------------- ---- \n");printf(" ----------- ------------ 4打印代码文件--- ---------- \n"); printf(" ----------- ------------ 5打印赫夫曼树--- ---------- \n");printf(" ----------- ------------ 0退出---------------------- ---- \n");printf(" ----------- ------------------- \n");}// 初始化函数,输入n 个字符及其对应的权值,根据权值建立哈夫曼树,并将其存于文件hfmtree 中void Init(){FILE *fp;int i,n,w[52]; // 数组存放字符的权值char character[52]; // 存放n 个字符printf("\n 输入字符个数n:");scanf("%d",&n); // 输入字符集大小printf(" 输入%d个字符及其对应的权值:\n",n);for (i=0;i<n;i++){char b=getchar();scanf("%c",&character[i]);scanf("%d",&w[i]); // 输入n 个字符和对应的权值}HuffmanCoding(HT,character,w,n); // 建立赫夫曼树if((fp=fopen("hfmtree.txt","w"))==NULL)printf("Open file hfmtree.txt error!\n");for (i=1;i<=2*n-1;i++){if(fwrite(&HT[i],sizeof(HTNode),1,fp)!=1) // 将建立的赫夫曼树存入文件hfmtree.txt 中printf("File write error!\n");}printf("\n 赫夫曼树建立成功,并已存于文件hfmtree.txt 中\n"); fclose(fp);// 建立赫夫曼树的算法void HuffmanCoding(HuffmanTree &HT,char *character,int *w,int n){int m,i,x,y;HuffmanTree p;if(n<=1) return;m=2*n-1;HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));for(p=HT+1,i=1;i<=n;++i,++p,++character,++w){p->ch=*character;p->weight=*w;p->parent=0;p->lchild=0;p->rchild=0 ;}for(;i<=m;++i,++p){p->ch=0;p->weight=0;p->parent=0;p->lchild=0;p->rchild=0;} for(i=n+1;i<=m;++i) {select(HT,i-1,&x,&y);HT[x].parent=i;HT[y].parent=i;HT[i].lchild=x;HT[i].rchild=y;HT[i].weight=HT[x].weight+HT[y].weight;}}// 从HT[1] 到HT[j] 中选择parent 为0,weight 最小的两个结点,用返回其x和y 序号void select(HuffmanTree HT,int j,int *x,int *y){int i;// 查找weight 最小的结点for (i=1;i<=j;i++)if (HT[i].parent==0){*x=i;break;}for (;i<=j;i++)if ((HT[i].parent==0)&&(HT[i].weight<HT[*x].weight))*x=i;HT[*x].parent=1;// 查找weight 次小的结点for (i=1;i<=j;i++)if (HT[i].parent==0){*y=i;break;}for (;i<=j;i++)if ((HT[i].parent==0)&&(i!=*x)&&(HT[i].weight<HT[*y].weight)) *y=i;// 对文件tobetrans 中的正文进行编码,然后将结果存入文件voidcodefile 中Coding(){FILE *fp,*fw;int i,f,c,start;char *cd; HuffmanCode HC;if(n==0)n=Read_tree(HT);// 从文件hfmtree.txt 中读入赫夫曼树, 返回叶子结点数// 求赫夫曼树中各叶子节点的字符对应的的编码,并存于HC指向的空间中{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';else cd[--start]='1';HC[i]=(char *)malloc((n-start)*sizeof(char)); strcpy(HC[i],&cd[start]); }free(cd);}if((fp=fopen("tobetrans.txt","rb"))==NULL)printf("Open file tobetrans.txt error!\n");if((fw=fopen("codefile.txt","wb+"))==NULL)printf("Open file codefile.txt error!\n");char temp;fscanf(fp,"%c",&temp); // 从文件读入第一个字符while(!feof(fp))}fclose(fw); fclose(fp); printf("\n 已将文件 hfmtree.txt 成功编码 , 并已存入codefile.txt 中! \n\n");}// 将文件 codefile 中的代码进行译码,结果存入文件 textfile 中 void Decoding(){FILE *fp,*fw; int m,i;char *code,*text,*p;if(n==0)n=Read_tree(HT);// 从文件 hfmtree.txt 中读入赫夫曼树 , 返回叶子结点 数if((fp=fopen("codefile.txt","rb"))==NULL) printf("Open file codefile.txt error!\n"); if((fw=fopen("textfile.txt","wb+"))==NULL) printf("Open file textfile.txt error!\n"); code=(char *)malloc(sizeof(char));fscanf(fp,"%c",code); // 从文件读入一个字符 for(i=1;!feof(fp);i++){code=(char *)realloc(code,(i+1)*sizeof(char)); // 增加空间 fscanf(fp,"%c",&code[i]); // 从文件读入下一个字符for(i=1;i<=n;i++)if(HT[i].ch==temp) break; // for(int r=0;HC[i][r]!='\0';r++) // fputc(HC[i][r],fw); fscanf(fp,"%c",&temp); //在赫夫曼树中查找字符所在的位置将字符对应的编码存入文件从文件读入下一个字符}code[i-1]='\0';// codefile.txt 文件中的字符已全部读入,存放在code 数组中text=(char *)malloc(100*sizeof(char));p=text;m=2*n-1;if(*code=='0')find(HT,code,text,HT[m].lchild,m); // 从根节点的左子树去找elsefind(HT,code,text,HT[m].rchild,m); // 从根节点的右子树去找for(i=0;p[i]!='\0';i++) // 把译码好的字符存入文件textfile.txt 中fputc(p[i],fw);fclose(fp);fclose(fw);printf("\n 已将codefile.txt 文件成功译码,兵已存入textfile.txt 文件!\n\n"); }// 将文件codefi1e 以紧凑格式显示在终端上, 每行50 个代码。