1、数据结构课程设计摘要哈夫曼编/译器设计: 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求这发送端通过一个编码系统对待传数据预先编码,在发送端将传来的数据进行译码(复原)。对于双工信道。每端都需要一个完整的编译码系统。本程序将为这样的信息收发站写一个哈夫曼的编译码系统。哈夫曼编码/译码程序运行步骤:字查找,从英文文章中识别出字符,并把字符插入到一棵二叉排序树中。哈夫曼树中序遍历,是为了把英文文章中的不重复的字符保存起来。哈夫曼编码,在已经构造好的霍夫曼树中从每个叶子结点出发追溯到树根,逆向找出霍夫曼树中叶子结点的编码,规定:树中每个结点的左分支标上0,
2、右分支标上1。哈夫曼译码利用霍夫曼树实现对产生的编码文件的译码,译码过程为:从根结点出发,按二进制位串的0或1进入左分支或右分支,当到达叶子结点时译出该叶子对应的单词或标点符号,若该编码文件尚未结束,则回到根结点继续进行上述过程。运行环境:windows XP 语言环境:简体中文 软件大小:51 KB 编写工具: Microsoft Visual studio 2008 AbstractInformation : Huffman coding used in communication can greatly improve the channel utilization, reduced t
3、ransmission time, and lower transmission costs. However, this requires that the sender through a coding system for pre-treatment data-coding, the transmitter will be sent for decoding data (recovery). For dual-channel. Each side needs a complete encryption system. This procedure will this informatio
4、n hubs Huffman was one of the encryption system. Hoffmann code for coding procedures to run the steps and : word from english in the words and punctuation marks;and insert the words, and punctuation marks a second sort of a tree. the traversal order hoffmann, to english articles do not repeat the wo
5、rds and punctuation marks. Hoffmann tree in order to traverse;keep the code has been constructed in hoffmann good hafman tree leaves from the start dates back to tabulate the roots; Hoffmann decoding;hafman the implementation of the code to the coding, coding procedures for : from start to tabulate
6、the roots of binary of 0 or 1 to the left or right, a subdivision of a branch is to tabulate the leaves of the leaves translate the words or punctuation marks, if the code file is not finished but is to tabulate the process of continuing. all the code, coding procedures are in the file.目 录一、问题描述4二、需
7、求分析4三、概要设计5四、数据结构设计7五、算法设计7六、程序测试与实现9七、调试分析12八、心得体会12一、问题描述1、题目内容:利用哈夫曼编码进行信息通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。试写一个哈夫曼编/译码系统。2、基本要求:一个完整的系统应具有以下功能:(1)初始化。从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件中。(2)编码。利用已建好的哈夫曼树对文件中的正文进行编码,然后将结果存入文件中。(3)译码。利用已建好的哈夫曼树将文件中的代码进
8、行译码,结果存入文件中。(4)完成数据测试,要求编码字符不低于15个,编码文件的长度不低于50个字符。 (5) 计算平均编码长度。二、需求分析一个完整的系统应具有以下功能:1、 初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立赫夫曼树。 对赫夫曼树初始化。 根据书本算法,对树进行从叶子到根的逆向求每个字符的赫夫曼编码。 更新赫夫曼树。2、 编码(Encoding)。利用已建好的哈夫曼树正文进行编码。 将终端输入须要编码的语句逐字在已建好的赫夫曼树中查找。 当在树中找到相匹配字符时,将该字符对应的赫夫曼编码同意保存。最后将数组中的编码在终端输出。3、
9、译码(Decoding)。利用已建好的哈夫曼树将文件中的代码进行译码。 获取须要译码的编码组。 将编码逐一读入,并在赫夫曼中根据左0右1去查找字符。 将译好的语句在终端输出。三、概要设计操作集合:void Select(int cur, int &r1, int &r2); nodes1 cur中选择双亲为,权值最小的两个结点r1,r2 void CreatHuffmanTree(char ch, int w, int n); public: HuffmanTree(char ch, int w, int n);由字符,权值和字符个数构造哈夫曼树 virtual HuffmanTree();
10、析构函数 string Encode(char ch); 编码 LinkList Decode(string strCode); 译码本程序主要用到了三个算法。(1)哈夫曼编码; 在初始化过程中间,要用输入的字符和权值建立哈夫曼树并求得哈夫曼编码。先将输入的字符和权值存放到一个结构体数组中,建立哈夫曼树,将计算所得的哈夫曼编码存储到另一个结构体数组中。(2)串的匹配; 在编码过程中间,要对已经编码过的代码译码,可利用循环,将代码中的与哈夫曼编码的长度相同的串与这个哈夫曼编码比较,如果相等就回显。(3)二叉树的遍历 在印哈夫曼树(T)的中,因为哈夫曼树也是二叉树,所以就要利用二叉树的先序遍历将哈
11、夫曼树输出。四、数据结构设计struct Node char data; / 节点数据域为字符型 Node *next; Node() next = NULL; Node(char item, Node *link = NULL) data = item; next = link; struct HuffmanTreeNode int weight; unsigned int parent, leftChild, rightChild; / 双亲,左右孩子域 HuffmanTreeNode(); HuffmanTreeNode(int w, int p = 0, int lChild = 0,
12、 int rChild = 0); 五、算法设计 1、算法分析(必须要用语言进行描述)构造树:初始化:每个字符就是一个结点,字符的频度就是结点的权: 1、将结点按频度从小到大排序; 2、选取频度最小的两个结点,以它们为儿子,构造出一个新的结点; 新结点的权值就是它两个儿子的权值之和; 构造之后,从原来的结点序列里删除刚才选出的那两个结点,但同时将新生成的结点加进去; 3、如果结点序列里只剩下一个结点,表示构造完毕,退出。 否则回到第一步。编码: 编码: 可以假定,对某个结点而言,其左孩子在当前阶段的编码为0,右孩子的编码为1。这样就可以通过”树的遍历“的方式来生成字长编码对照表 来到这里,基本
13、上艰苦的已经完成了,对某个具体的字符串编码和解码就只是简单的“查表替换”的工作了。解码: 解码也是个简单的查表、替换过程。如果利用该种编码发送字符串,则它的”字宁含编码侧应表也必须发送过去,不然对方是不知道怎么解码的。 对给出的一串编码,从左向右,将编码组合起来并查表.2、算法流程图结束传入参数:结点个数n动态分配内存,声明哈夫曼树HT,并对其值进行初始化建哈夫曼树,依次在HT1.i-1中Select parent为0且weight最小的两个结点分配n个字符编码的头指针向量和求编码的工作区间从叶子到根逆向逐个字符求哈夫曼编码释放工作空间开始I=n?六、程序测试与实现1、函数之间的调用关系2、主
14、程序int main(void)char *ch; int *w,n,i; cout输入字符集中字符的个数:n; ch=new charn; w=new intn; cout输入字符集中的字符:endl; for(i=0;ichi; cout输入字符集中的字符的权值:endl; for(i=0;iwi; HuffmanTree hmTree(ch, w, n); string strText,strCode; coutstrText; cout 文本串 strText.c_str() 编码为:; for (int pos = 0; pos strText.length(); pos+) str
15、ing strTmp = hmTree.Encode(strTextpos); cout strTmp.c_str(); cout endl; system(PAUSE); coutstrCode; cout 编码串 strCode.c_str()来表示P所指的变量,又由于结点类型是一个结构类型,因此可用P data和Pnext分别表示结点的数据域变量和指针域变量。指针变量的值要么为空(NULL),不指向任何结点;要么其值为非空,即它的值是一个结点的存储地址。注意,当P为空值时,则它不指向任何结点,此时不能通过P来访问结点,否则会引起程序错误。八、心得体会 通过这次数据结构课程设计,使我对软件
16、的界面设计有了一个比较深刻的了解,对各种内部排序方法的性能有了清晰的认识,使我感觉到到,一个优秀的软件,不仅仅是可以运行的,更应该具有人性化的界面,协调的布局,合理的结构,良好的性能和一定的容错性一个人要完成所有的工作是非常困难和耗时的.在以后的学习中我会更加注意各个方面的能力的协调发展,选择一两门技术进行深入研究,成为一个既可以统筹全局.又有一定技术专长的优秀的程序开发人员. 通过这次实验我也着实又感受了一次编程的乐趣,从中也学到了不少知识。虽然都说“程序=数据结构+算法”,但我在学习运用数据结构编程之前,并没能深刻体会到这一点,直到这次课设实践。现在编程感觉完全不同了。在编写一个程序之前,
17、自己能够综合考各种因素,首先选取自己需要的数据结构,是树还是图或是别的什么?然后选定一种或几种存储结构来具体的决定后面的函数的主要风格。最后在编写每一个函数之前,可以仔细斟酌比对,挑选出最适合当前状况的算法。这样,即使在完整的程序还没有写出来之前,自己心中已经有了明确的原图了。这样无形中就提高了自己编写的程序的质量。另外,我还体会到深刻理解数据结构的重要性。只有真正理解这样定义数据类型的好处,才能用好这样一种数据结构。了解典型数据结构的性质是非常有用的,它往往是编写程序的关键。我以前对递归算法一直很害怕,总是看不明白究竟这递归是怎么进行的。在这次实验中我终于克服了这一障碍,一次次单步执行书中递归函数的例子,并一遍遍在心中自己默默的走,终于弄明白了,真的是功夫不负有心人啊!同时我还根据自己的理解写出了类似的递归函数实现了新的功能,真是受益良多啊!在这次实验中,我对参数的调用也进行了很多种尝试,己经能够相对准确的选择合适的参数形式来实现函数之间的数据传输交互了。.忽略此处.12