信息论与编码课程设计(哈夫曼编码的分析与实现)
信息论与编码课程设计--统计信源熵与哈夫曼编码

信息论与编码课程设计--统计信源熵与哈夫曼编码信息论与编码课程设计信息论与编码课程设计报告设计题目:统计信源熵与哈夫曼编码专业班级学号学生姓名指导教师教师评分2015年 3 月 25 日1信息论与编码课程设计目录一、设计任务与要求...................................................................... ...........................................3 二、设计思路...................................................................... .......................................................3 三、设计流程图...................................................................... (5)四、程序运行及结果...................................................................... ...........................................6 五、心得体会...................................................................... . (8)参考文献...................................................................... (9)附录:源程序...................................................................... .. (10)2信息论与编码课程设计一、设计任务与要求1.1设计目的信息论与编码是信息、通信、电子工程专业的基础,对理论研究和工程应用均有重要的作用。
数据结构设计课程设计-哈夫曼编译码系统的设计与实现

20180902一、需求分析1、问题描述利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(解码)。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。
试为这样的信息收发站设计一个哈夫曼编译码系统。
2、基本要求(1)初始化(Initialzation)。
从数据文件DataFile.txt中读入字符及每个字符的权值,建立哈夫曼树HuffTree;(2)编码(EnCoding)。
用已建好的哈夫曼树,对文件ToBeTran.txt 中的文本进行编码形成报文,将报文写在文件Code.txt中;(3)译码(Decoding)。
利用已建好的哈夫曼树,对文件CodeFile.txt 中的代码进行解码形成原文,结果存入文件Textfile.txt中;(4)输出(Output)。
输出DataFile.txt中出现的字符以及各字符出现的频度(或概率);输出ToBeTran.txt及其报文Code.txt;输出CodeFile.txt及其原文Textfile.txt;二、概要设计1.数据结构本程序需要用到以一个结构体HTNode,以及一个二维数组HuffmanCode。
2.程序模块本程序包含两个模块,一个是实现功能的函数的模块,另一个是主函数模块。
系统子程序及功能设计本系统共有七个子程序,分别是:a.int min1(HuffmanTree t,int i)//进行比较b.void select(HuffmanTree t,int i,int *s1,int *s2)//求权值最小的两个数c.void HuffmanCoding(HuffmanTree *HT,HuffmanCode *HC,int *w,char *u,int n)///* w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n 个字符的赫夫曼编码HC */d.void Initialzation(HuffmanTree *HT,HuffmanCode *HC)//初始化e.int EnCoding(HuffmanTree *HT,HuffmanCode *HC)//对文件ToBeTran.txt中的文本进行编码形成报文,将报文写在文件Code.txt 中f.int pipei(char *c,int n,HuffmanCode *HC)//在huffmancode寻找匹配的编码g.void Decoding(HuffmanTree *HT,HuffmanCode *HC)//对文件CodeFile.txt中的代码进行解码形成原文,结果存入文件Textfile.txt中3.各模块之间的调用关系以及算法设计主函数调用Initialzation,EnCoding,Decoding。
课程设计-哈夫曼编码的分析和实现

课程设计任务书2010—2011学年第一学期专业:通信工程学号:070110101 姓名:苟孟洛课程设计名称:信息论与编码课程设计设计题目:哈夫曼编码的分析与实现完成期限:自2010 年12月20 日至2010 年12 月26 日共1 周一.设计目的1、深刻理解信源编码的基本思想与目的;2、理解哈夫曼编码方法的基本过程与特点;3、提高综合运用所学理论知识独立分析和解决问题的能力;4、使用MATLAB或其他语言进行编程。
二.设计内容假设已知一个信源的各符号概率,编写适当函数,对其进行哈夫曼编码,得出码字,平均码长和编码效率,总结此编码方法的特点和应用。
三.设计要求1、编写的函数要有通用性;2、信源可以自由选择,符号信源与图像信源均可。
四.设计条件计算机、MATLAB或其他语言环境五、参考资料[1]曹雪虹,张宗橙.信息论与编码.北京:清华大学出版社,2007.[2]王慧琴.数字图像处理.北京:北京邮电大学出版社,2007.指导教师(签字):教研室主任(签字):批准日期:年月日摘要哈夫曼编码(Huffman Coding)是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。
在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩。
这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。
这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。
本课题通过MATLAB编写适当的函数,对一个随机信源进行哈夫曼编码,得出码字,平均码长和编码效率。
从而理解信源编码的基本思想与目的以及哈夫曼编码方法的基本过程与特点,并且提高综合运用所学理论知识独立分析和解决问题的能力。
信息论课程实验报告—哈夫曼编码

*p2 = j;
}
}
void CreateHuffmanTree(HuffmanTree T)
{
int i,p1,p2;
InitHuffmanTree(T);
InputWeight(T);
for(i = n;i < m;i++)
4)依次继续下去,直至信源最后只剩下两个信源符号为止,将这最后两个信源符号分别用二元码符号“0”和“1”表示;
5)然后从最后—级缩减信源开始,进行回溯,就得到各信源符号所对应的码符号序列,即相应的码字。
四、实验目的:
(1)进一步熟悉Huffman编码过程;(2)掌握C语言递归程序的设计和调试技术。以巩固课堂所学编码理论的知识。
#include "stdio.h"
#include "stdlib.h"
#include <float.h>
#include <math.h>
#define n 8
#define m 2*n-1
typedef struct
{
float weight;
int lchild,rchild,parent;
}
}
void InputWeight(HuffmanTree T)
{
float temp[n] = {0.20,0.18,0.17,0.15,0.15,0.05,0.05,0.05};
for(int i = 0;i < n;i++)
T[i].weight = temp[i];
}
c哈夫曼编码课程设计

c 哈夫曼编码课程设计一、课程目标知识目标:1. 学生能理解哈夫曼编码的基本原理,掌握其构建过程和应用场景。
2. 学生能运用哈夫曼编码进行数据压缩,并了解压缩比的概念。
3. 学生能理解哈夫曼编码在通信、图像处理等领域的重要性。
技能目标:1. 学生能够运用所学知识,独立构建哈夫曼树并进行编码。
2. 学生能够分析给定数据,选择合适的编码方法进行数据压缩。
3. 学生能够运用编程工具实现哈夫曼编码和解码过程。
情感态度价值观目标:1. 学生通过学习哈夫曼编码,培养对数据压缩技术的兴趣,提高信息素养。
2. 学生在合作学习过程中,培养团队协作能力和沟通能力。
3. 学生了解我国在数据压缩领域的研究成果,增强民族自豪感。
课程性质:本课程为信息技术课程,旨在帮助学生掌握数据压缩的基本方法,提高数据处理能力。
学生特点:学生处于高年级阶段,具备一定的编程基础和逻辑思维能力。
教学要求:结合学生特点和课程性质,注重理论与实践相结合,培养学生的实际操作能力和创新能力。
通过分解课程目标为具体学习成果,使学生在学习过程中能够明确自身的学习进度和目标。
二、教学内容1. 哈夫曼编码基本原理:介绍哈夫曼编码的概念、原理和优势,结合教材相关章节,使学生理解哈夫曼编码在数据压缩中的应用。
- 哈夫曼树的构建方法- 哈夫曼编码的生成过程- 压缩比的概念及其计算方法2. 哈夫曼编码的实际操作:通过实际操作,让学生掌握哈夫曼编码的构建和编码过程。
- 利用编程工具实现哈夫曼树的构建- 编程实现哈夫曼编码的生成- 数据压缩与解压缩的实际操作3. 哈夫曼编码的应用案例分析:结合教材案例,分析哈夫曼编码在通信、图像处理等领域的作用。
- 通信领域的数据压缩- 图像处理中的哈夫曼编码应用- 其他领域中的应用案例4. 编程实践:布置相关编程任务,巩固学生对哈夫曼编码的理解和应用。
- 实现哈夫曼编码的压缩和解压缩程序- 分析不同数据集的压缩效果,优化哈夫曼编码方法教学内容安排和进度:第1课时:哈夫曼编码基本原理及构建方法第2课时:哈夫曼编码的实际操作(构建哈夫曼树、生成编码)第3课时:哈夫曼编码的应用案例分析第4课时:编程实践(实现压缩与解压缩程序,优化编码方法)三、教学方法本课程将采用以下教学方法,以促进学生的主动参与和深入理解:1. 讲授法:对于哈夫曼编码的基本原理和概念,通过教师清晰的讲解,结合教材内容,使学生快速掌握理论基础。
信息论与编码课程设计 河南理工大学

一设计目的信息论与编码是我们电子信息工程的一门重要的专业课,通过对本次课程设计,学习将学到的理论知识用于实践,同时也学习了用软件编写程序,进一步对本课程知识的巩固和理解。
学习分析问题,解决问题的方法和途径,提高对本专业的学习兴趣。
二设计任务与要求(1)统计信源熵要求:统计任意文本文件中各字符(不区分大小写)数量,计算字符概率,并计算信源熵。
(2)哈夫曼编码要求:任意输入消息概率,利用哈夫曼编码方法进行编码,并计算信源熵和编码效率。
三理论简介3.1通信系统的模型通信系统的模型通信系统的性能指标主要是有效性、可靠性、安全性和经济性,通信系统优化就是使这些指标达到最佳,除了经济性,这些指标正是信息论的研究对象,可以通过各种编码处理来使通信系统的性能最优化。
根据信息论的各种编码定理和上述通信系统的指标,编码问题可以分为3类:信源编码、信道编码和加密编码。
3.1.1 信源编码由于信源符号之间存在分布不均匀和相关性,使得信源存在冗余度,信源编码的主要任务就是减少冗余度,提高编码效率。
信源编码的基础是信息论中的两个编码定理:无失真编码定理和限失真编码定理。
前者适用于离散信源或数字信号;后者主要用于连续信源或模拟信号。
本次课程设计就是利用的无失真信源编码。
3.1.2 信道编码信源编码器的作用:把信源发出的消息变换成由二进制码元(或多进制码元)组成的代码组,这种代码组就是基带信号。
同时通过信源编码可以压缩信源的冗余度,以提高通信系统传输消息的效率。
信源译码器的作用:把信道译码器输出的代码组变换成信宿所需要的消息形式,它的作用相当于信源编码器的逆过程。
3.1.3 加密编码加密编码是研究如何隐蔽消息中的信息内容,以便在传输过程中不被窃听,提高通信系统的安全性。
3.2 信源熵3.2.1 信源的描述和分类& 按信源在时间和幅度上的分布情况离散信源:文字、数据、电报连续信源:语音、图像& 按发出符号的数量单个符号信源:指信源每次只发出一个符号代表一个消息符号序列信源:指信源每次发出一组含二个以上符号的符号序列代表一个消息 & 按符号间的关系无记忆信源有记忆信源3.2.2 离散信源熵& 自信息量:随机事件的自信息量定义为其概率对数的负值,即在信息论中常用的对数底是2,信息量的单位为比特(bit);& 联合自信息量两个消息xi ,yj 同时出现的联合自信息量:& 条件自信息量在事件yj 出现的条件下,随机事件xi 发生的条件概率为p(xi / yj) ,则它的条件自信息量定义为条件概率对数的负值:& 离散信源熵为信源中各个符号不确定度的数学期望,即单位为:比特/符号 或者 比特/符号序列。
哈夫曼编码译码的设计与实现数据结构课程设计

《数据结构》课程设计题目--哈夫曼编码/译码的设计与实现班级:13数据库一班学号:1315925280姓名:吴松指导教师:王超目录目录 (1)一、需求分析 (2)二、设计要求 (2)三、概要设计 (2)1、流程图 (2)2、设计包含的几个部分 (4)四、详细设计 (2)五、显示结果………………………………………………9.六、心得体会 (10)七、参考文献 (11)哈夫曼编码译码一、需求分析在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,赫夫曼编码正是一种应用广泛且非常有效的数据压缩技术。
哈夫曼编码是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。
哈弗曼编码使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。
这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。
赫夫曼编码的应用很广泛,利用赫夫曼树求得的用于通信的二进制编码称为赫夫曼编码。
树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个叶子对应的字符的编码,这就是赫夫曼编码。
哈弗曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符串。
二、设计要求对输入的一串电文字符实现赫夫曼编码,再对赫夫曼编码生成的代码串进行译码,输出电文字符串。
通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。
电报通信是传递文字的二进制码形式的字符串。
但在信息传递时,总希望总长度能尽可能短,即采用最短码。
假设每种字符在电文中出现的次数为Wi,编码长度为Li,电文中有n种字符,则电文编码总长度为∑WiLi。
哈夫曼编码课程设计

中南林业科技大学本科课程设计说明书学院:理学院专业年级:08信息与计算科学课程:信息论与编码课程设计设计题目: Huffman编码的设计与实现指导教师:龚志伟2011年5月学生姓名:夏文林学号:20083728 分工:程序调试、资料收集学生姓名:易勋学号:20083730分工:源程序、算法分析学生姓名:游斌学号:20083731 分工:文档整理、源程序学生姓名:余璐学号:20083732 分工:源程序、总结学生姓名:朱健学号:20083736 分工:源程序、流程分析与编写中文摘要哈夫曼编码是广泛用于数据文件压缩的十分有效的编码方法。
其压缩通常在20%~90%之间。
哈夫曼编码算法使用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式。
哈夫曼算法构造的扩充二叉树称为哈夫曼编码树或哈夫曼树。
当然,还有编码和译码部分。
本系统的前端开发工具是Visual C++6.0。
具有输入字符集大小及权值大小,构造哈夫曼树,并对用户输入的字符串进行编码以及译码还有退出四种功能。
本程序经过测试后,功能均能实现,运行稳定。
关键词:哈夫曼树,编码,权值英文摘要Huffman coding is widely used in data file compression coding method is very effective. The compression usually between 20% ~ 90% in. Huffman use of the character encoding algorithm in the document appeared in frequency table with 0 to build a string of optimal each character said means.The algorithm's construction huffman extended binary tree called huffman coding tree or huffman tree. Of course, there are coding and decoding parts. This system the front-end development tools is Visual c + + 6.0. With input character set size and weitht size, structure tree huffman, and user input string coding and decoding and exit four functions. This procedure after testing, functions are realized, steady operation.目录引言 (4)1、问题分析 (5)2、算法设计 (6)3、算法实现 (6)3.1流程图 (6)3.2程序代码 (7)3.3调试结果 (10)3.3.1例题5—7的测试结果 (10)3.3.2习题5-12的调试结果 (11)4、结论 (13)5、参考文献 (13)引言哈夫曼在上世纪五十年代初就提出这种编码时,根据字符出现的概率来构造平均长度最短的编码。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
建筑大学电气与电子信息工程学院信息理论与编码课程设计报告设计题目:哈夫曼编码的分析与实现专业班级:电子信息工程 101 学生:学号:指导教师:吕卅王超设计时间: 2013.11.18-2013.11.29一、设计的作用、目的《信息论与编码》是一门理论与实践密切结合的课程,课程设计是其实践性教学环节之一,同时也是对课堂所学理论知识的巩固和补充。
其主要目的是加深对理论知识的理解,掌握查阅有关资料的技能,提高实践技能,培养独立分析问题、解决问题及实际应用的能力。
通过完成具体编码算法的程序设计和调试工作,提高编程能力,深刻理解信源编码、信道编译码的基本思想和目的,掌握编码的基本原理与编码过程,增强逻辑思维能力,培养和提高自学能力以及综合运用所学理论知识去分析解决实际问题的能力,逐步熟悉开展科学实践的程序和方法二、设计任务及要求通过课程设计各环节的实践,应使学生达到如下要求:1. 理解无失真信源编码的理论基础,掌握无失真信源编码的基本方法;2. 掌握哈夫曼编码/费诺编码方法的基本步骤及优缺点;3. 深刻理解信道编码的基本思想与目的,理解线性分组码的基本原理与编码过程;4. 能够使用MATLAB 或其他语言进行编程,编写的函数要有通用性。
三、设计容一个有8个符号的信源X ,各个符号出现的概率为:编码方法:先将信源符号按其出现的概率大小依次排列,并取概率最小的字母分别配以0和1两个码元(先0后1或者先1后0,以后赋值固定),再将这两个概率相加作为一个新字母的概率,与未分配的二进制符号的字母重新排队。
并不断重复这一过程,直到最后两个符号配以0和1为止。
最后从最后一级开始,向前返回得到各个信源符号所对应的码元序列,即为对应的码字。
哈夫曼编码方式得到的码并非唯一的。
在对信源缩减时,两个概率最小的符号合并后的概率与其他信源符号的概率相同时,这两者在缩减中的排序将会导12345678,,,,,()0.40.180.10.10.070.060.050.04X x x x x x x x x P X ⎡⎤⎧⎫=⎨⎬⎢⎥⎣⎦⎩⎭致不同码字,但不同的排序将会影响码字的长度,一般讲合并的概率放在上面,这样可获得较小的码方差。
四、设计原理4.1哈夫曼编码步骤(1)将信源消息符号按照其出现的概率大小依次排列为≥Λ12p≥pnp≥(2)取两个概率最小的字母分别配以0和1两个码元,并将这两个概率相加作为一个新的概率,与未分配的二进制符号的字母重新排队。
(3)对重新排列后的两个最小符号重复步骤(2)的过程。
(4)不断重复上述过程,知道最后两个符号配以0和1为止。
(5)从最后一级开始,向前返回得到的各个信源符号所对应的码元序列,即为相应的码字。
4.2哈夫曼编码特点哈夫曼编码是用概率匹配的方法进行信源匹配方法进行信源。
它的特点是:(1)哈夫曼的编码方法保证了概率大的符号对应于短码,概率小的符号对应于长码,充分应用了短码。
(2)缩减信源的最后两个码字总是最后一位不同,从而保证了哈夫曼编码是即时码。
(3)哈夫曼编码所形成的码字不是唯一的,但编码效率是唯一的,在对最小的两个速率符号赋值时可以规定大的为“1”,小得为“0”,如果两个符号的出现概率相等时,排列时无论哪个在前都可以,所以哈夫曼所构造的码字不是唯一的,对于同一个信息源,无论上述的顺序如何排列,他的平均码长是不会改变的,所以编码效率是唯一的。
(4)只有当信息源各符号出现的概率很不平均的时候,哈夫曼编码的效果才明显。
(5)哈夫曼编码必须精确的统计出原始文件中每个符号出现频率,如果没有这些精确的统计将达不到预期效果。
哈夫曼编码通常要经过两遍操作,第一遍进行统计,第二遍产生编码,所以编码速度相对慢。
另外实现电路复杂,各种长度的编码的编译过程也是比较复杂的,因此解压缩的过程也比较慢。
(6)哈夫曼编码只能用整数来表示单个符号,而不能用小数,这很大程度上限制了压缩效果。
哈夫曼所有位都是合在一起的,如果改动其中一位就可以使其数据变得面目全非。
五、设计步骤5.1以框图形式画出哈夫曼编码过程(哈夫曼编码要求构建哈夫曼树)。
表1 哈夫曼编码哈夫曼树:给定n个实数w1,w2,......,wn(n≥2),求一个具有n个结点的二叉数,使其带权路径长度最小。
所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。
树的带权路径长度为WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),N 个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。
可以证明哈夫曼树的WPL是最小的。
(1)根据与n个权值{w1,w2…wn}对应的n个结点构成具有n棵二叉树的森林F={T1,T2…Tn},其中第i棵二叉树Ti(1 ≤ i ≤ n)都只有一个权值为wi的根结点,其左、右子树均为空。
(2) 在森林F 中选出两棵根结点的权值最小的树作为一棵新树的左、右子树,且置新树的根结点的权值为其左、右子树上根结点权值之和。
(3)从F 中删除构成新树的那两棵,同时把新树加入F 中。
(4)重复第(2)和第(3)步,直到F 中只含有一棵为止,此树便为Huffman 树。
图1哈夫曼树5.2计算平均码长、编码效率、冗余度。
平均码长为:K =∑=81i )(Ki xi p =0.4×1+0.18×3+0.1×3+0.1×4+0.07×4+0.06×4+0.05×5+0.04×5=2.61(码元/符号)信源熵为:∑===ni xi p xi p X H 1)(log )()(-(0.4log0.4+0.18log0.18+0.1log0.1+0.1log0.1+0.07+log0.07+0.06log0.06+0.05log0.05+0.04log0.04) =2.55bit/符号信息传输速率为:R=KX H )(=61.255.2=0.977bit/码元 编码效率为: η=KX H )(=61.255.2=0.977 冗余度为:γ=1-η=1-0.977=0.六、哈夫曼编码的实现6.1软件介绍Visual C++ 6.0,简称VC 或者VC6.0,是微软推出的一款C++编译器,将“高级语言”翻译为“机器语言(低级语言)”的程序。
Visual C++是一个功能强大的可视化软件开发工具。
自1993年Microsoft 公司推出Visual C++1.0后,随着其新版本的不断问世,Visual C++已成为专业程序员进行软件开发的首选工具。
Visual C++6.0由Microsoft 开发, 它不仅是一个C++ 编译器,而且是一个基于Windows 操作系统的可视化集成开发环境(integrated development environment ,IDE )。
Visual C++6.0由许多组件组成,包括编辑器、调试器以及程序向导AppWizard 、类向导Class Wizard 等开发工具。
这些组件通过一个名为Developer Studio 的组件集成为和谐的开发环境。
Microsoft 的主力软件产品。
Visual C++是一个功能强大的可视化软件开发工具。
Visual C++6.0以拥有“语法高亮”,自动编译功能以及高级除错功能而著称。
比如,它允许用户进行远程调试,单步执行等。
还有允许用户在调试期间重新编译被修改的代码,而不必重新启动正在调试的程序。
其编译及创建预编译头文件(stdafx.h)、最小重建功能及累加连结(link)著称。
这些特征明显缩短程序编辑、编译及连结的时间花费,在大型软件计划上尤其显著。
(1)Developer Studio 这是一个集成开发环境,我们日常工作的99%都是在它上面完成的,再加上它的标题赫然写着“Microsoft Visual C++”,所以很多人理所当然的认为,那就是Visual C++了。
其实不然,虽然Developer Studio 提供了一个很好的编辑器和很多Wizard ,但实际上它没有任何编译和程序的功能,真正完成这些工作的幕后英雄后面会介绍。
我们也知道,Developer Studio 并不是专门用于VC的,它也同样用于VB,VJ,VID等Visual Studio家族的其他同胞兄弟。
所以不要把Developer Studio当成Visual C++,它充其量只是Visual C++的一个壳子而已。
这一点请切记!(2)MFC从理论上来讲,MFC也不是专用于Visual C++,Borland C++,C++Builder 和Symantec C++同样可以处理MFC。
同时,用Visual C++编写代码也并不意味着一定要用MFC,只要愿意,用Visual C++来编写SDK程序,或者使用STL,ATL,一样没有限制。
不过,Visual C++本来就是为MFC打造的,Visual C++中的许多特征和语言扩展也是为MFC而设计的,所以用Visual C++而不用MFC就等于抛弃了Visual C++中很大的一部分功能。
但是,Visual C++也不等于MFC。
(3)Platform SDK这才是Visual C++和整个Visual Studio的精华和灵魂,虽然我们很少能直接接触到它。
大致说来,Platform SDK是以Microsoft C/C++编译器为核心(不是Visual C++,看清楚了),配合MASM,辅以其他一些工具和文档资料。
上面说到Developer Studio没有编译程序的功能,那么这项工作是由谁来完成的呢?是CL,是NMAKE,和其他许许多多命令行程序,这些我们看不到的程序才是构成Visual Studio的基石。
6.2 编程//**哈夫曼编码**#include <iostream.h>#include <math.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <vector>using namespace std;struct Huffman_InformationSource{char InformationSign[10];double Probability;char Code[10];int CodeLength;;};struct HuffNode{char InformationSign[10];double Probability;HuffNode *LeftSubtree,*middleSubtree,*RightSubtree,*Next;char Code[10];int CodeLength;};class CHuffman_2{public:CHuffman_2(){ISNumber=0;AvageCodeLength=0.0;InformationRate=0.0;CodeEfficiency=0.0;Redundancy=0.0;}CHuffman_2(){DestroyBTree(HuffTree);}void Huffman_Input();void Huffman_Sort();void Huffman_Tree();void Huffman_Coding();void Huffman_CodeAnalyzing();void Huffman_Display();void DestroyBTree(HuffNode *TreePointer);private:vector<Huffman_InformationSource>ISarray;int ISNumber;double AvageCodeLength;double InformationRate;double CodeEfficiency;HuffNode * HuffTree;private:void Huffman_Code(HuffNode *TreePointer);};//输入信源信息void CHuffman_2::Huffman_Input(){Huffman_InformationSource temp1={"x1",0.40,"",0};ISarray.push_back(temp1);Huffman_InformationSource temp2={"x2",0.18,"",0};ISarray.push_back(temp2);Huffman_InformationSource temp3={"x3",0.10,"",0};ISarray.push_back(temp3);Huffman_InformationSource temp4={"x4",0.10,"",0};ISarray.push_back(temp4);Huffman_InformationSource temp5={"x5",0.07,"",0};ISarray.push_back(temp5);Huffman_InformationSource temp6={"x6",0.06,"",0};ISarray.push_back(temp6);Huffman_InformationSource temp7={"x7",0.05,"",0};ISarray.push_back(temp7);Huffman_InformationSource temp8={"x8",0.04,"",0};ISarray.push_back(temp8);ISNumber=ISarray.size();}//按概率“从大到小”排序void CHuffman_2::Huffman_Sort(){Huffman_InformationSource temp;int I,j;for(i=0;i<ISNumber-1;i++)for(j=i+1;j<ISNumber;j++)if(ISarray[i].Probability<ISarray[j].Probability){temp=ISarray[i];ISarray[i]=ISarray[j];ISarray[j]=temp;}}void CHuffman_2::Huffman_Tree(){int I;HuffNode *ptr1,*ptr2,*ptr3,*ptr4,*temp1,*temp2;ptr1=new HuffNode;strcpy(ptr1->InformationSign,ISarray[0].InformationSign);ptr1->Probability=ISarray[0].Probability;strcpy(ptr1->Code,ISarray[0].Code);ptr1->LeftSubtree=NULL;ptr1->middleSubtree =NULL;ptr1->RightSubtree=NULL;ptr1->Next=NULL;HuffTree=ptr1;for(i=1;i<ISNumber;i++){ptr2=new HuffNode;strcpy(ptr2->InformationSign,ISarray[i].InformationSign);ptr2->Probability=ISarray[i].Probability;strcpy(ptr2->Code,ISarray[i].Code);ptr2->LeftSubtree=NULL;ptr2->middleSubtree =NULL;ptr2->RightSubtree=NULL;ptr2->Next=ptr1;ptr1=ptr2;}HuffTree=ptr1;int k;int s;k=ceil((double)(ISNumber-3)/(3-1));s=3+k*(3-1)-ISNumber;if(s==1){ptr2=ptr1->Next;ptr4=new HuffNode;strcpy(ptr4->InformationSign,"*");ptr4->Probability=ptr1->Probability+ptr2->Probability;strcpy(ptr4->Code,"");ptr4->LeftSubtree =NULL;ptr4->middleSubtree=ptr1;ptr4->RightSubtree=ptr2;HuffTree=ptr2->Next;temp1=HuffTree;while(temp1&&(ptr4->Probability>temp1->Probability)) {temp2=temp1;temp1=temp1->Next;}ptr4->Next=temp1;if(temp1==HuffTree)HuffTree=ptr4;elsetemp2->Next=ptr4;ptr1=HuffTree;}while(ptr1->Next){//合并概率最小的结点ptr2=ptr1->Next;ptr3=ptr2->Next;ptr4=new HuffNode;strcpy(ptr4->InformationSign,"*");ptr4->Probability=ptr1->Probability+ptr2->Probability +ptr3->Probability;strcpy(ptr4->Code,"");ptr4->LeftSubtree=ptr1;ptr4->middleSubtree=ptr2;ptr4->RightSubtree=ptr3;HuffTree=ptr3->Next;temp1=HuffTree;while(temp1&&(ptr4->Probability>temp1->Probability)){temp2=temp1;temp1=temp1->Next;}ptr4->Next=temp1;if(temp1==HuffTree)HuffTree=ptr4;elsetemp2->Next=ptr4;ptr1=HuffTree;}//释放:ptr1=NULL;ptr2=NULL;ptr3=NULL;ptr4=NULL;temp1=NULL;temp2=NULL;strcpy(HuffTree->Code,"");HuffTree->CodeLength=0;}//生成哈夫曼码void CHuffman_2::Huffman_Code(HuffNode *TreePointer){if (TreePointer == NULL)return;char tempstr[10]="";if(!TreePointer->LeftSubtree&&!TreePointer->middleSubtree &&!TreePointer->RightSubtree){for(int i=0;i<ISNumber;i++)if(strcmp(ISarray[i].InformationSign,TreePointer->InformationSign )==0){strcpy(ISarray[i].Code,TreePointer->Code);ISarray[i].CodeLength=TreePointer->CodeLength;return;}return;}if(TreePointer->LeftSubtree){strcpy(tempstr,TreePointer->Code);strcat(tempstr,"2");strcpy(TreePointer->LeftSubtree->Code,tempstr);TreePointer->LeftSubtree->CodeLength=TreePointer->CodeLength+1;Huffman_Code(TreePointer->LeftSubtree);}if(TreePointer->middleSubtree){strcpy(tempstr,TreePointer->Code);strcat(tempstr,"1");strcpy(TreePointer->middleSubtree->Code,tempstr);TreePointer->middleSubtree->CodeLength=TreePointer->CodeLength+1;Huffman_Code(TreePointer->middleSubtree);}if(TreePointer->RightSubtree){strcpy(tempstr,TreePointer->Code);strcat(tempstr,"0");strcpy(TreePointer->RightSubtree->Code,tempstr);TreePointer->RightSubtree->CodeLength=TreePointer->CodeLength+1;Huffman_Code(TreePointer->RightSubtree);}}void CHuffman_2::Huffman_Coding(){Huffman_Code(HuffTree);}//编码结果void CHuffman_2::Huffman_CodeAnalyzing(){for(int i=0;i<ISNumber;i++)AvageCodeLength+=ISarray[i].Probability*ISarray[i].CodeLength;int L=1;int m=2; /InformationRate=AvageCodeLength/L*(log(m)/log(2));double Hx=0;for(int j=0;j<ISNumber;j++)Hx+=-ISarray[j].Probability*log(ISarray[j].Probability)/log(2);CodeEfficiency=Hx/InformationRate;Redundancy=1- CodeEfficiency;}void CHuffman_2::Huffman_Display(){cout<<"码字:"<<endl;for(int i=0;i<ISNumber;i++){cout<<"\'"<<ISarray[i].InformationSign<<"\'"<<":"<<ISarray[i].Code<<endl;}cout<<endl;cout<<"平均码长:"<<AvageCodeLength<<endl<<endl;cout<<"编码效率:"<<CodeEfficiency<<endl<<endl;cout<<"冗余度:"<< Redundancy <<endl<<endl;}void CHuffman_2::DestroyBTree(HuffNode *TreePointer){if (TreePointer!= NULL){DestroyBTree(TreePointer->LeftSubtree);DestroyBTree(TreePointer->middleSubtree);DestroyBTree(TreePointer->RightSubtree);delete TreePointer;TreePointer = NULL;}}void main(){CHuffman_3 YYY;YYY.Huffman_Input();YYY.Huffman_Sort();YYY.Huffman_Tree();YYY.Huffman_Coding();YYY.Huffman_CodeAnalyzing();YYY.Huffman_Display();}6.3 运行结果及分析图2 运行结果运行结果分析:从运行结果上可以看出,该结果与理论计算一致,并且可以看出哈夫曼编码的特点:(1)哈夫曼的编码方法保证了概率大的符号对应于短码,概率小的符号对应于长码,充分应用了短码。