3.5 主函数执行情况
执行程序时,首先进入main函数,通过输入0,1,2,3,4来选择是显示哈夫曼树还是哈夫曼编码或者是编码译码功能。将数据保存在文件中,则是通过问件的I/O流读写,进行文件与内存间数据的输入输出。
1 2 3 5 7 图2.2 主函数流程
选择步骤1后,程序将进行以下操作:首先,定义一个数组char ch[]用来存储叶结点所代表的字符;然后,定义一个weight用来表示字符在电文中出现的频率;再根据叶结点的权值建立哈夫曼树,将哈夫曼树初始化,输入待编码的字符及带权值,输入叶结点所代表的字符及带权值,然后进行并和,新结点存储于tree中;选出两个权值最小的根结点,将其命名为p1和p2,改变最小权值和次小权值及其对应位置,设置新结点的双亲指针,则最小根结点是新结点的左孩子,次小根结点是新结点的右孩子,新结点权值是两孩子权值之和,将根结点的双亲结点设置为0,哈弗曼算法采用带双亲的孩子链表作为结点的存储结构。
选择步骤2后,程序将进行以下操作:首先,建立哈夫曼树;然后利用哈夫曼树进行编码,实际上就是求出从根结点到叶结点的路径。由于采用带双亲的孩子链表作为存储结构,因此对于电文中的每个字符,可以从哈夫曼树的叶结点出发,沿结点的双亲链回溯到根结点,从而确定其路径。在整个回溯过程中,每回溯一步就会遇到哈夫曼树的一个分支,从而得到一个哈夫曼编码。显然,这样生成的代码序列与要求的编码次序相反,因此,可定义一个数组bits,将生成的代码序列从后向前依次存放到位串数组bits中,并用一个变量start表示哈夫曼编码在位串数组中的起始位置,当某个字符编码完成时,从变量的start处开始将编码复制到该字符对应的数组bits中即可。由于字符集大小为叶子结点总数leafnum,故不等长编码的长度不会超过leafnum,再加上结束符号’\0’,位串数组bits的大小应为leafnum+1。然后,再定义一个ch用来存储编码字符的名称;在函数体内定义一个huftree tree[]用来存储已建哈夫曼树的结点,hufcode code[]用来存储字符的哈夫曼编码表,定义buf作为临时变量,用于存储编码位串。P为树的双亲结点,若为树的左分支,则生成代码0,若为树的右分支,则生成代码1,然后将第i个字符编码存到编码表code[i]中,在运行界面中会出现每个字符的哈夫曼编码以及字符名称、字符位串和位串的起始位置。
选择步骤3后,程序将进行以下操作:哈夫曼译码过程与编码过程相反,译码过程就是分解电文中字符串的过程,具体步骤如下:首先输入要译电文的二进制编码,然后从哈夫曼的根节点出发,对于电文的二进制编码,按照二进制位串中的0和1确定是进入左分支还是右分支;若编码为0,则进入结点的左孩子,否则进入结点的右孩子;一旦达到叶结点,就译出该结点所代表的字符;若电文没有结束,则重新输入一串新的二进制编码,回到根结点继续进行译码,直到二进制电文全部译完为止;如果被译的二进制编码的最后部分不能成为前缀中的序列,可添加0或添加1,直至译完为止。则在运行界面上将出现输入的字符串及其相对应的二进制编码。会计内部控制英文文献和翻译
选择步骤5后,程序将进行以下操作:首先利用函数fopen()打开文件,将存盘文件手动建立(也可自动生成)在相应的地区,将要写入文件的字符串在运行界面中输入,然后利用getchar()函数,将字符串读入文件中,直到出现结束符“*”,则停止读入;再在建立文件的地区打开该文件,则在文件中可以显示出在运行界面中输入的字符串以及其相应的二进制编码;若未在相应的地区建立存盘文件,则程序运行会出现“Open file failed!”,表示文件打开失败,而自动生成文件则可避免这一纰漏,最后写上一个fclose()函数,关闭开始所打开的文件。而后在上一个步骤之后进行文件的读出,输入想要译码的字符串对应的二进制编码,则在对应的存盘文件中将会出现该二进制编码及其对应的字符串。
上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] 下一页