- 浏览: 1028302 次
-
文章分类
最新评论
-
l67721363:
感谢分享,要是有各个函数性能比较就好了。
SQL优化 数据库优化 -
hanmiao:
此图片来自QQ空间,未经允许不可引用。
Hacking QQ空间
霍夫曼树
看完后评论评论
数据结构与算法设计课程设计
专业 班级 学号 姓名(签名) 完成日期 指导教师(签名)
【设计题目】字符与霍夫曼代码的转换
【问题描述】
用霍夫曼编码的方式压缩数据,为实现霍夫曼代码与原文件ASIC码之间的对照,把压缩过程中原文件生成的霍夫曼代码保存与一个文件中。给出用霍夫曼压缩的代码,要把霍夫曼代码转换成明文件保存于文件中。
【软件功能】
读取文本文档中的字符转换成霍夫曼代码保存于另一个文件中。并能够读取霍夫曼代码转换成字符保存于另一个文件中。
【算法思想】 首先定义256个统计字符出现频数的静态数组,其数组的下标对应着每一个字符。
对读入的字符进行统计时,直接根据字符的ASIIC码找到相应的元素。
生成霍夫曼代码:
字符出现的频数统计完成后检查每个字符出现的频数,把频数不为零的元素添加到搜索二叉树中。添加完成后,遍历搜索二叉树,每遍历一个节点添加到霍夫曼树中。当霍夫曼树建立完成后遍历霍夫曼树,记录遍历节点所对应的霍夫曼编码,每遍历一个叶子节点,对叶子节点的数据域赋上霍夫曼编码。
搜索二叉树和霍夫曼树中节点的数据域为指针,直接指向定义的统计字符出现频数的静态数组元素。所以对搜索二叉树和霍夫曼树节点的数据域的操作就等于直接对定义的静态数组的成员操作。
字符与霍夫曼代码的对照表单独保存于一个文件中。其文件名由保存霍夫曼代码的文件名决定。
重新读取文件,读取的字符直接根据其ASIIC码直接找到保存该字符的数组元素。然后把其代表的霍夫曼编码写入文件。
霍夫曼代码转换成字符:
首先读取字符与霍夫曼代码的对照表,根据霍夫曼编码中1出现的次数作为下表保存在静态数组中。
读取霍夫曼代码,读取的时候如果读取的字符是‘1’则继续读,如果为‘0’则暂时停止。根据读取1的个数找到相应的静态数组元素,把相应的字符写入文件中。然后字把统计1出现的整数赋0,重新读取字符。
【类的设计】
统计字符串的类
class CharacterStat{
public:
static char a;
char character; //字符
int frequence; //频数
char * HuffStat; //字符对应的霍夫曼代码,采用指针的形式,在赋值的时候分配内存
int iHuff; //霍夫曼编码转换成的整形数
public:
CharacterStat();
~CharacterStat();
};
搜索二叉树的节点类
class BSTNode{
friend class BST;
friend class huffmantree;
CharacterStat * data;//数据域,采用指针的形式,因为是指向已分配好的地址。
BSTNode *leftchild;
BSTNode *rightchild;
int Threaded; //线索化标记(中序线索化)
public:
BSTNode(CharacterStat *p=NULL);//构造函数
~BSTNode();
};
搜索二叉树类
class BST{
BSTNode *root;
public:
void Destory();
BSTNode * GetRoot();
BST(CharacterStat * p=NULL );
bool AddANode( CharacterStat *);
};
霍夫曼类
class huffmantree{
BSTNode *root;//霍夫曼树的跟节点
public:
bool DestoryHuffman();
huffmantree(CharacterStat * p=NULL); //默认参数,建立对象时给对象初始化
bool AddToRoot(CharacterStat *); //把一个节点增加到已建好的霍夫曼树中
bool BuiltHuffmanTree(BSTNode *);//对一个空的霍夫曼树建立霍夫曼树,传过来的指针为搜索二叉树的跟节点
bool InorderBST(BSTNode *);//中序遍历搜索二叉树,把搜索二叉树中的节点增加到霍夫曼树中
bool InorderHuffman(BSTNode *);//中序遍历霍夫曼树,主要目的在于给字符附上霍夫曼编码
BSTNode * getroot();//得到霍夫曼树的跟节点
};
【存储结构设计】
统计字符的对象:采用静态存储方式,定义255个对象(ASIIC中有255个字符,包括扩展字符)。
搜索二叉树节点对象:采用堆存储方式,动态的分配内存,而且对象中的数据域只存放指针。
其逻辑关系满足搜索二叉树的定义。
字符与霍夫曼编码的对应关系存放于保存霍夫曼编码文件路径下,其文件名为保存霍夫曼代码文件名后加HMcode.如保存霍夫曼代码的文件名为huff.txt,则其对应关系文件名为huffHMcode.txt
要进行霍夫曼编码的文件为用户指定路径下的文件。
对用霍夫曼编码保存的文件为用户指定路径下的文件。
【模块流程图】
1.文本文件转换为霍夫曼编码
已定义好统计字符频数的静态数组frequencearray[255]。
<group id="_x0000_s1026" style="MARGIN-TOP: 0px; Z-INDEX: 1; LEFT: 0px; MARGIN-LEFT: 0px; WIDTH: 414pt; POSITION: absolute; HEIGHT: 600.6pt; TEXT-ALIGN: left" coordsize="8280,12012" coordorigin="1800,2064"><rect id="_x0000_s1027" style="LEFT: 1800px; WIDTH: 8280px; POSITION: absolute; TOP: 2064px; HEIGHT: 12012px"><textbox><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-RIGHT: #ece9d8; BORDER-TOP: #ece9d8; BORDER-LEFT: #ece9d8; BORDER-BOTTOM: #ece9d8; BACKGROUND-COLOR: transparent"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font size="3">统计字符出现的频数</font></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font size="3">用户指定路径,并用只读的方式打开指定路径下的文件。</font></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font size="3">进入读文件循环,条件为没有读到文件结尾。</font></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US"><font face="Times New Roman"><span style="mso-spacerun: yes"> </span>Fin>>a;frequencearray[a]++;//</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">相应的字符频数加</span><span lang="EN-US"><font face="Times New Roman">1</font></span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font size="3">统计完成,把频数不为零的字符添加到搜索二叉树中。</font></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font size="3">比较搜索二叉树当前的元素</font></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">比当前元素大</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其他情况</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当前元素的右孩子</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其他</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当前元素的左</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其他</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 15.75pt; mso-char-indent-count: 1.5"><font size="3"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指针为空</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">孩子指针为空</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">添加到节点</span><font face="Times New Roman"> </font><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当前指针指向</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">添加到节点</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当前指针指向</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><font size="3"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打断循环</span><span lang="EN-US"><font face="Times New Roman"><span style="mso-spacerun: yes"> </span><span style="mso-spacerun: yes"></span></font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它继续比较</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打断循环</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它继续比较</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font size="3">搜索二叉树建立完成,把搜索二叉树转换成霍夫曼扩展二叉树。</font></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中序遍历搜索二叉树,复制遍历的节点</span><span lang="EN-US"><font face="Times New Roman">A</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">添加到扩展二叉树中。</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US"><font face="Times New Roman"><span style="mso-spacerun: yes"> </span>New node</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,添加到扩展二叉树的</span><span lang="EN-US"><font face="Times New Roman">root</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">节点。</span><span lang="EN-US"><font face="Times New Roman">Node->leftchild=root;node->rightchild=&A</font></span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">遍历霍夫曼树,生成霍夫曼编码;先定义</span><span lang="EN-US"><font face="Times New Roman">CString string;int i=0;</font></span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">向</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">左</span><span lang="EN-US"><font face="Times New Roman"><span style="mso-spacerun: yes"> </span><span style="mso-spacerun: yes"></span></font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">向</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">右</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 15.75pt; mso-char-indent-count: 1.5"><font size="3"><span lang="EN-US"><font face="Times New Roman">string[i]=</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">‘</span><chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="’"><span lang="EN-US"><font face="Times New Roman">0</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">’</span></chmetcnv><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,然后赋给所指向的</span><span lang="EN-US"><font face="Times New Roman"><span style="mso-spacerun: yes"> </span>string[i++]=</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">‘</span><chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="’"><span lang="EN-US"><font face="Times New Roman">1</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">’</span></chmetcnv><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,继续遍历,如果遍历完</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 52.5pt; mso-char-indent-count: 5.0"><font size="3"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">统计字符对象</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">成,把</span><span lang="EN-US"><font face="Times New Roman">string</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">赋给所只相当统计字符对象</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 15.75pt; mso-char-indent-count: 1.5"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font size="3">重新读取文件,译成霍夫曼编码写入新文件中。</font></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US"><font face="Times New Roman"><span style="mso-spacerun: yes"> </span>Fin>>a</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">;</span><span lang="EN-US"><font face="Times New Roman">fout<<frequencearray[a].huffstat</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">;</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US"><font face="Times New Roman">ASIIC</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与霍夫曼代码的转换完毕</span></font></p> </div> </td> </tr></tbody></table></textbox></rect><line id="_x0000_s1028" style="POSITION: absolute" to="10080,2532" from="1800,2532"><font size="3"></font></line><line id="_x0000_s1029" style="POSITION: absolute" to="10080,3156" from="1800,3156"><font size="3"></font></line><line id="_x0000_s1030" style="POSITION: absolute" to="10080,3780" from="2160,3780"><font size="3"></font></line><line id="_x0000_s1031" style="POSITION: absolute" to="10080,4404" from="1800,4404"><font size="3"></font></line><line id="_x0000_s1032" style="POSITION: absolute" to="2160,4404" from="2160,3780"><font size="3"></font></line><line id="_x0000_s1033" style="POSITION: absolute" to="10080,5028" from="1800,5028"><font size="3"></font></line><line id="_x0000_s1034" style="POSITION: absolute" to="10080,5652" from="2160,5652"><font size="3"></font></line><line id="_x0000_s1035" style="POSITION: absolute" to="10080,6276" from="2160,6276"><font size="3"></font></line><line id="_x0000_s1036" style="POSITION: absolute" to="2160,8148" from="2160,5652"><font size="3"></font></line><line id="_x0000_s1037" style="POSITION: absolute" to="10080,7212" from="2160,7212"><font size="3"></font></line><line id="_x0000_s1038" style="POSITION: absolute" to="10080,8148" from="1800,8148"><font size="3"></font></line><line id="_x0000_s1039" style="POSITION: absolute" to="4140,8148" from="4140,6276"><font size="3"></font></line><line id="_x0000_s1040" style="POSITION: absolute" to="5940,8148" from="5940,5652"><font size="3"></font></line><line id="_x0000_s1041" style="POSITION: absolute" to="8100,8148" from="8100,6276"><font size="3"></font></line><line id="_x0000_s1042" style="POSITION: absolute" to="10080,8772" from="1800,8772"><font size="3"></font></line><line id="_x0000_s1043" style="POSITION: absolute" to="10080,9396" from="2160,9396"><font size="3"></font></line><line id="_x0000_s1044" style="POSITION: absolute" to="10080,10020" from="1800,10020"><font size="3"></font></line><line id="_x0000_s1045" style="POSITION: absolute" to="2160,10020" from="2160,9396"><font size="3"></font></line><line id="_x0000_s1046" style="POSITION: absolute" to="10080,10644" from="2160,10644"><font size="3"></font></line><line id="_x0000_s1047" style="POSITION: absolute" to="10080,11268" from="2160,11268"><font size="3"></font></line><line id="_x0000_s1048" style="POSITION: absolute" to="2160,12204" from="2160,10644"><font size="3"></font></line><line id="_x0000_s1049" style="POSITION: absolute" to="10080,12204" from="1800,12204"><font size="3"></font></line><line id="_x0000_s1050" style="POSITION: absolute" to="5580,12204" from="5580,10644"><font size="3"></font></line><line id="_x0000_s1051" style="POSITION: absolute" to="10080,12828" from="2160,12828"><font size="3"></font></line><line id="_x0000_s1052" style="POSITION: absolute" to="10080,13452" from="1800,13452"><font size="3"></font></line><line id="_x0000_s1053" style="POSITION: absolute" to="2160,13452" from="2160,12828"><font size="3"></font></line></group>
2.霍夫曼代码转换为原文件
<group id="_x0000_s1054" style="MARGIN-TOP: 0px; Z-INDEX: 2; LEFT: 0px; MARGIN-LEFT: 0px; WIDTH: 414pt; POSITION: absolute; HEIGHT: 226.2pt; TEXT-ALIGN: left" coordsize="8280,4524" coordorigin="1800,2220"><rect id="_x0000_s1055" style="LEFT: 1800px; WIDTH: 8280px; POSITION: absolute; TOP: 2220px; HEIGHT: 4524px"><textbox><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-RIGHT: #ece9d8; BORDER-TOP: #ece9d8; BORDER-LEFT: #ece9d8; BORDER-BOTTOM: #ece9d8; BACKGROUND-COLOR: transparent"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font size="3">打开字符与霍夫曼代码的对照表文件,读取统计对象。</font></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">根据霍夫曼编码转换成的整数大小建立搜索二叉树</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font size="3">关闭文件,打开霍夫曼代码文件。</font></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">读取霍夫曼代码,</span><span lang="EN-US"><font face="Times New Roman">(</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">把霍夫曼代码按整形数输入</span><span lang="EN-US"><font face="Times New Roman">)</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">定义一个</span><span lang="EN-US"><font face="Times New Roman">int i=0</font></span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">读入整形数</span><span lang="EN-US"><font face="Times New Roman">1<span style="mso-spacerun: yes"> </span></font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">读取整形数</span><span lang="EN-US"><font face="Times New Roman">0<span style="mso-spacerun: yes"> </span></font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其他</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman" size="3"> </font></span></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US"><font face="Times New Roman"><span style="mso-spacerun: yes"> </span>I++<span style="mso-spacerun: yes"> </span></font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在搜索二叉树中找相应</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">输出文件错误,提示不是霍夫</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 131.25pt; mso-char-indent-count: 12.5"><font size="3"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的源码写入另一个文件</span><span lang="EN-US"><span style="mso-spacerun: yes"><font face="Times New Roman"> </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">曼代码文件,并退出程序。</span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><p><font face="Times New Roman" size="3"></font></p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font size="3">转换完毕</font></span></p> </div> </td> </tr></tbody></table></textbox></rect><line id="_x0000_s1056" style="POSITION: absolute" to="10080,2688" from="2160,2688"><font size="3"></font></line><line id="_x0000_s1057" style="POSITION: absolute" to="10080,3312" from="1800,3312"><font size="3"></font></line><line id="_x0000_s1058" style="POSITION: absolute" to="2160,3312" from="2160,2688"><font size="3"></font></line><line id="_x0000_s1059" style="POSITION: absolute" to="10080,3936" from="1800,3936"><font size="3"></font></line><line id="_x0000_s1060" style="POSITION: absolute" to="10080,4560" from="2160,4560"><font size="3"></font></line><line id="_x0000_s1061" style="POSITION: absolute" to="2160,6120" from="2160,4560"><font size="3"></font></line><line id="_x0000_s1062" style="POSITION: absolute" to="10080,5184" from="2160,5184"><font size="3"></font></line><line id="_x0000_s1063" style="POSITION: absolute" to="10080,6120" from="1800,6120"><font size="3"></font></line><line id="_x0000_s1064" style="POSITION: absolute" to="4320,6120" from="4320,4560"><font size="3"></font></line><line id="_x0000_s1065" style="POSITION: absolute" to="7020,6120" from="7020,4560"><font size="3"></font></line></group>
<group id="_x0000_s1066" style="MARGIN-TOP: 7.8pt; Z-INDEX: 3; LEFT: 0px; MARGIN-LEFT: 0px; WIDTH: 441pt; POSITION: absolute; HEIGHT: 171.6pt; TEXT-ALIGN: left" coordsize="8820,3432" coordorigin="1800,1908"><rect id="_x0000_s1067" style="LEFT: 5580px; WIDTH: 1620px; POSITION: absolute; TOP: 1908px; HEIGHT: 780px"><textbox style="mso-next-textbox: #_x0000_s1067"><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-RIGHT: #ece9d8; BORDER-TOP: #ece9d8; BORDER-LEFT: #ece9d8; BORDER-BOTTOM: #ece9d8; BACKGROUND-COLOR: transparent"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">主函数</span><span lang="EN-US" style="FONT-SIZE: 14pt"><p></p></span></p> </div> </td> </tr></tbody></table></textbox></rect><rect id="_x0000_s1068" style="LEFT: 8820px; WIDTH: 1800px; POSITION: absolute; TOP: 3936px; HEIGHT: 1404px"><textbox><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-RIGHT: #ece9d8; BORDER-TOP: #ece9d8; BORDER-LEFT: #ece9d8; BORDER-BOTTOM: #ece9d8; BACKGROUND-COLOR: transparent"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">显示霍夫曼编码文件</span><span lang="EN-US" style="FONT-SIZE: 14pt"><p></p></span></p> </div> </td> </tr></tbody></table></textbox></rect><rect id="_x0000_s1069" style="LEFT: 6480px; WIDTH: 1980px; POSITION: absolute; TOP: 3936px; HEIGHT: 1404px"><textbox><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-RIGHT: #ece9d8; BORDER-TOP: #ece9d8; BORDER-LEFT: #ece9d8; BORDER-BOTTOM: #ece9d8; BACKGROUND-COLOR: transparent"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: 350%; TEXT-ALIGN: center" align="center"><span style="FONT-SIZE: 14pt; LINE-HEIGHT: 350%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">显示原文件</span><span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 350%"><p></p></span></p> </div> </td> </tr></tbody></table></textbox></rect><rect id="_x0000_s1070" style="LEFT: 4140px; WIDTH: 2160px; POSITION: absolute; TOP: 3936px; HEIGHT: 1404px"><textbox><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-RIGHT: #ece9d8; BORDER-TOP: #ece9d8; BORDER-LEFT: #ece9d8; BORDER-BOTTOM: #ece9d8; BACKGROUND-COLOR: transparent"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对指定文件进行霍夫曼解码</span><span lang="EN-US" style="FONT-SIZE: 14pt"><p></p></span></p> </div> </td> </tr></tbody></table></textbox></rect><rect id="_x0000_s1071" style="LEFT: 1800px; WIDTH: 2160px; POSITION: absolute; TOP: 3936px; HEIGHT: 1404px"><textbox><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-RIGHT: #ece9d8; BORDER-TOP: #ece9d8; BORDER-LEFT: #ece9d8; BORDER-BOTTOM: #ece9d8; BACKGROUND-COLOR: transparent"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对指定文件进行霍夫曼编码</span><span lang="EN-US" style="FONT-SIZE: 14pt"><p></p></span></p> </div> </td> </tr></tbody></table></textbox></rect><line id="_x0000_s1072" style="POSITION: absolute" to="6480,3312" from="6480,2688"></line><line id="_x0000_s1073" style="POSITION: absolute; flip: x" to="9720,3312" from="2700,3312"></line><line id="_x0000_s1074" style="POSITION: absolute" to="9720,3936" from="9720,3312"><stroke endarrow="block"></stroke></line><line id="_x0000_s1075" style="POSITION: absolute" to="7380,3936" from="7380,3312"><stroke endarrow="block"></stroke></line><line id="_x0000_s1076" style="POSITION: absolute" to="5220,3936" from="5220,3312"><stroke endarrow="block"></stroke></line><line id="_x0000_s1077" style="POSITION: absolute" to="2700,3936" from="2700,3312"><stroke endarrow="block"></stroke></line></group>【模块划分及调用关系】
【界面设计】
主页面:
用户选择操作代码,分别进入不同的界面:
1. 原文件转换为霍夫曼代码;2.霍夫曼代码转换为原文件
3. 显示原文件 4.显示霍夫曼编码文件
Esc键退出
进入不同界面时,提示当前的操作。如输入文件名,按任意键等。
【用户手册】
1、 程序上机调试报告
【语法错误及其排除】
1. 对同一个指针在不同的函数进行释放内存。解决方法,对同一类指针释放内存统一化。
2. 错误的认为把指针所指的内存释放掉了其指针就为NULL指针了。解决方法,给指针重新赋上NULL。
【算法错误及其排除】
2、 程序测试结果
【测试数据】
原文件的内容:
<shapetype id="_x0000_t75" coordsize="21600,21600" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 468pt; HEIGHT: 112.5pt" type="#_x0000_t75"><imagedata cropright="14340f" cropleft="8533f" cropbottom="36132f" croptop="19508f" o:title="" src="file:///C:/DOCUME~1/JJJ/LOCALS~1/Temp/msohtml1/01/clip_image004.png"></imagedata></shape>
【输出结果】
转换为霍夫曼编码后文件的内容:
<shape id="_x0000_i1026" style="WIDTH: 414pt; HEIGHT: 207pt" type="#_x0000_t75"><imagedata cropright="24295f" cropleft="4266f" cropbottom="32847f" croptop="11339f" o:title="" src="file:///C:/DOCUME~1/JJJ/LOCALS~1/Temp/msohtml1/01/clip_image006.png"><font face="Times New Roman" size="3"></font></imagedata></shape>
把霍夫曼编码转换为原文件为:
<shape id="_x0000_i1027" style="WIDTH: 441pt; HEIGHT: 83.25pt" type="#_x0000_t75"><imagedata cropright="20028f" cropleft="4266f" cropbottom="44375f" croptop="12160f" o:title="" src="file:///C:/DOCUME~1/JJJ/LOCALS~1/Temp/msohtml1/01/clip_image008.png"><font size="3"></font></imagedata></shape>
【程序性能评价】
1.在控制台下运行稳定,能够读取文件中的所有字符进行统计(包括不显示字符);
2.统计速度较快,因为没有循环比较过程,直接通过字符的ASIIC码找到相应的字符结构。
3.转换速度也一样较快,因为和统计的原理一样,没有循环比较过程;
4.文件中的字符与霍夫曼编码能够一字不差的进行转换;
5.在对字符出现频率进行排列是采用搜索二叉树的,并且对搜索二叉树进行线索化,很大程度上提高的遍历速度;
6.搜索二叉树和霍夫曼树的节点的数据域都为指针,指向静态数组的元素,这样即节省了空间上的开销,又方便了操作。
7.交互能力较好,避免了用户不必要的输入,如用户输入文件的扩展名;
8.错误处理能力较好,函数返回值一般用bool 用于判断函数执行的效果等;
【性能改进方向】
1. 加强错误处理能力,特别是自动处理能力;
2. 在类中多增加成员函数和变量,以便以后的升级及用在别的场合;
3. 增加显示目录的函数,使之能够查看在不用目录下的所有文本文件,以更方便操作;
4. 增加退出操作,如当输入空文件名时直接返回上一级目录;
5. 修改交互界面,使之更加友好等;
6.
【收获及体会】
最刚开始学霍夫曼编码时觉得这有点难,可当自己亲手把它做出来时就有一种熟悉的感觉。做一个程序能锻炼很多东西,在其中的收获也不少。这次做霍夫曼树的程序,让我更加清楚了自己当前的编程水平及还需提高的方向。
3、 源程序代码
#include<iostream.h>
#include<fstream.h>
#include<string.h>
#include<stdlib.h>
#include<conio.h>
#include<stdio.h>
//声明类
class BSTNode;
class BST;
class huffmantree;
//统计字符串的类
class CharacterStat{
public:
static char a;
char character; //字符
int frequence; //频数
char * HuffStat; //字符对应的霍夫曼代码,采用指针的形式,在赋值的时候分配内存
int iHuff; //霍夫曼编码转换成的整形数
public:
CharacterStat();
~CharacterStat();
};
//************************************************************
char CharacterStat::a=0;
CharacterStat::CharacterStat(){
character=(char)a;frequence=0;HuffStat=0;iHuff=-1;a++;
}
//************************************************************
CharacterStat::~CharacterStat(){
}
//搜索二叉树的节点类
class BSTNode{
friend class BST;
friend class huffmantree;
CharacterStat * data;//数据域,采用指针的形式,因为是指向已分配好的地址。
BSTNode *leftchild;
BSTNode *rightchild;
int Threaded; //线索化标记(中序线索化)
public:
BSTNode(CharacterStat *p=NULL);//构造函数
~BSTNode();
};
//************************************************************
BSTNode::BSTNode(CharacterStat * p){
data=p;
leftchild=NULL;
rightchild=NULL;
}
//************************************************************
BSTNode::~BSTNode(){
// delete leftchild;
// delete rightchild;
}
//搜索二叉树类
class BST{
BSTNode *root;
public:
void Destory();
BSTNode * GetRoot();
BST(CharacterStat * p=NULL );
bool AddANode( CharacterStat *);
};
//************************************************************
BST::BST( CharacterStat* p){
if(p)
root= new BSTNode(p);
else
root=NULL;
}
//************************************************************
bool BST::AddANode( CharacterStat * p){
if(!p){
cerr<<"传过来的指针为空,无法增加节点!!!/n";
return false;
}
BSTNode * temp=root;
BSTNode * father=NULL;
if(!root){
root=new BSTNode(p);
root->Threaded=1;
return true;
}
while(temp){
if(p->frequence>temp->data->frequence)
if(temp->rightchild&&!temp->Threaded)//右孩子存在,且没有线索化
temp=temp->rightchild;
else{
father=temp->rightchild;//线索化要指向的目的
temp->Threaded=0;//消去原有的线索化标记,接上右孩子
temp->rightchild=new BSTNode(p);
temp->rightchild->rightchild=father;
temp->rightchild->Threaded=1;//标识线索化
break;
}
else if(temp->leftchild)
temp=temp->leftchild;
else{
temp->leftchild=new BSTNode(p);
temp->leftchild->rightchild=temp;
temp->leftchild->Threaded=1;//已进行线索化了
break;
}
}
return true;
}
//************************************************************
BSTNode * BST::GetRoot(){
return root;
}
//************************************************************
//霍夫曼树类
class huffmantree{
BSTNode *root;//霍夫曼树的跟节点
public:
bool DestoryHuffman();
huffmantree(CharacterStat * p=NULL); //默认参数,建立对象时给对象初始化
bool AddToRoot(CharacterStat *); //把一个节点增加到已建好的霍夫曼树中
bool BuiltHuffmanTree(BSTNode *);//对一个空的霍夫曼树建立霍夫曼树,传过来的指针为搜索二叉树的跟节点
bool InorderBST(BSTNode *);//中序遍历搜索二叉树,把搜索二叉树中的节点增加到霍夫曼树中
bool InorderHuffman(BSTNode *);//中序遍历霍夫曼树,主要目的在于给字符附上霍夫曼编码
BSTNode * getroot();//得到霍夫曼树的跟节点
};
//************************************************************
huffmantree::huffmantree(CharacterStat * pNode){
if(pNode){
root=new BSTNode(pNode);
}
}
//************************************************************
bool huffmantree::AddToRoot(CharacterStat * pNode){
BSTNode * Root;//将成为新的根节点
if(pNode){
Root=new BSTNode(NULL);//其数据域为空,其实际数据为其左孩子指针和右孩子指针
Root->leftchild=new BSTNode(pNode);//其右孩子指向新分配的内存地址
Root->rightchild=root; //交换跟节点
root=Root; //
return true; //成功返回真
}
return false;//失败返回假
}
//************************************************************
bool huffmantree::BuiltHuffmanTree(BSTNode *Node=NULL){
if(!Node){//没有传数据域的跟指针或跟指针为空时
cerr<<"数据域为空,不能建立霍夫曼树!!!/n";
return false;
}
InorderBST(Node);//采用中序遍历添加到霍夫曼树中
return true;
}
//************************************************************
bool huffmantree::InorderBST(BSTNode * Node=NULL){
BSTNode *temp=Node;
if(!Node){
cerr<<"遍历的数据域为空!!!/n";
return false;
}
while(temp->leftchild)//找第一个要遍历的节点,因为是线索化的
temp=temp->leftchild;
while(temp){//开始遍历
AddToRoot(temp->data);
if(temp->Threaded)//如果当前节点已线索化
temp=temp->rightchild;
else{//当前节点没有线索化
temp=temp->rightchild;
while(temp&&temp->leftchild)//找最左边的节点
temp=temp->leftchild;
}
}
return true;
}
//************************************************************
bool huffmantree::InorderHuffman(BSTNode * Node=NULL){
if(!Node){
cerr<<"霍夫曼树为空,不能遍历!!!";
return false;
}
char code[256];
BSTNode * temp=Node;
for(int i=0;temp;i++){
if(temp->leftchild){
code[i]='0';code[i+1]=0;
temp->leftchild->data->HuffStat=new char[i+2];
strncpy(temp->leftchild->data->HuffStat,code,i+2);
temp->leftchild->data->iHuff=i;
temp=temp->rightchild;
code[i]='1';
}
else{
code[i]='1';code[i+1]=0;
temp->data->HuffStat=new char[i+1];
strncpy(Node->data->HuffStat,code,i+1);
temp->data->iHuff=i;
temp=temp->rightchild;
}
}
return true;
}
//************************************************************
BSTNode * huffmantree::getroot(){
return root;
}
//************************************************************
//定义全局变量
CharacterStat frequence[256];
CharacterStat huffcode[256];
BST bst;//搜索二叉树
huffmantree huffman;//霍夫曼树
//************************************************************
bool textconvertohuffman(){
char a;
char filename[26];
char fileto[30];
char filefrom[30];
ifstream fin;
ofstream fout;
while(1){
system("cls");
cerr<<"/n/n/n/t请输入要转换的文件名(不要输扩展名):";
cin>>filename;
sprintf(filefrom,"%s%s",filename,".txt");
system("cls");
fin.open(filefrom);
if(fin.fail()){
fin.close();
cout<<"/n/t所指定的文件不存在或路径错误!!!/n退出请按Esc键,按其他键重新输入文件名"<<endl;
if(getch()==27){
system("cls");
return false;
}
}
else break;
}
cout<<"/n/n/t正在统计字符出现的频率......."<<endl;
a=fin.get();
while(!fin.eof()){
frequence[a].frequence++;
a=fin.get();
}
fin.close();
system("cls");
cout<<"/n/n/t统计完毕,正在建立搜索二叉树........."<<endl;
for(int i=0;i<256;i++){
if(frequence[i].frequence)
bst.AddANode(&frequence[i]);
}
cout<<"/n/n/t搜索二叉树建立完成,正遍历搜索二叉树建立霍夫曼树......."<<endl;
huffman.InorderBST(bst.GetRoot());
cout<<"/n/n/t霍夫曼树建立完毕,正遍历霍夫曼树给字符赋上霍夫曼代码......."<<endl;
huffman.InorderHuffman(huffman.getroot());
cout<<"/n/n/t字符赋上霍夫曼代码完成"<<endl;
cerr<<"/n/n/t请输入保存霍夫曼代码的文件名(不用输扩展名):";
cin>>filename;
sprintf(fileto,"%s%s",filename,".txt");
fin.open(filefrom);
fout.open(fileto);
if(fout.fail()){
system("cls");
cerr<<"/n/n/t文件不存在或无法新建";
system("cls");
return false;
}
i=0;
a=fin.get();
while(!fin.eof()){
fout<<frequence[a].HuffStat;
i+=frequence[a].iHuff;
if(i>80){
fout<<"/n";
i=0;
}
a=fin.get();
}
fin.close();
fout.close();
sprintf(filename,"%s%s",filename,"HMcode.txt");
fout.open(filename);
for(i=0;i<256;i++){
if(frequence[i].frequence)
fout<<frequence[i].iHuff<<"/t"<<(int)frequence[i].character<<"/t"
<<frequence[i].frequence<<"/t"<<frequence[i].HuffStat<<endl;
}
fout.close();
system("cls");
cout<<"/n/n/t按回车键显示字符与霍夫曼代码的对应关系"<<endl;
if(getch()==13){
system("cls");
cout<<"/n/t字符与霍夫曼代码的对应关系如下:"<<endl;
cout<<"ASIIC码 字符 二进制整形数 霍夫曼编码"<<endl;
for(i=0;i<256;i++){
if(frequence[i].frequence){
cout<<(int)frequence[i].character<<'/t'<<frequence[i].character<<"/t"<<frequence[i].iHuff<<"/t"
<<frequence[i].HuffStat<<endl;
}
}
cout<<"按任意键确定"<<endl;
getch();
}
for(i=0;i<256;i++)//执行完成,把所分配的内存释放掉
if(frequence[i].frequence){
frequence[i].frequence=0;
frequence[i].iHuff=0;
delete frequence[i].HuffStat;
}
huffman.DestoryHuffman();
bst.Destory();
system("cls");
return true;
}
//************************************************************
bool huffmanconvertotext(){
char filename[26];
char filefrom[30];
char fileto[30];
char i;
int a=0,b,c;
ifstream fin;
ofstream fout;
system("cls");
cerr<<"/n/n/t请输入保存霍夫曼代码的文件名(不要输扩展名):";
cin>>filename;
sprintf(filefrom,"%s%s",filename,".txt");
sprintf(filename,"%s%s",filename,"HMcode.txt");
fin.open(filename);
fin>>b;//读入频数
while(!fin.eof()){
huffcode[b].iHuff=b;
fin>>c>>huffcode[b].frequence;
huffcode[b].character=c;
huffcode[b].HuffStat=new char[b+2];
fin>>huffcode[b].HuffStat;
fin>>b;
}
fin.close();
system("cls");
cerr<<"/n/t请输入保存文件的名称(不要输扩展名):";
cin>>filename;
sprintf(fileto,"%s%s",filename,".txt");
fin.open(filefrom);
fout.open(fileto);
while(!fin.eof()){
fin>>i;
if(i=='1')
a++;
else if(i=='0'){
fout<<huffcode[a].character;
a=0;
}
else{
cout<<"/n/t文件中保存的不是霍夫曼代码,退出执行!!!/n"
<<"/n/t按任意键确定"<<endl;
getch();
system("cls");
return false;
}
}
system("cls");
return true;
}
//************************************************************
bool Readfile(){
ifstream fin;
char filename[30];
char a;
system("cls");
cerr<<"/n/n/t请输入要显示的原文件名称(不要输扩展名):";
cin>>filename;
sprintf(filename,"%s%s",filename,".txt");
fin.open(filename);
a=fin.get();
while(!fin.eof()){
cout<<a;
a=fin.get();
}
cout<<"/n/n/t按任意键确定"<<endl;
getch();
return true;
}
//************************************************************
bool ReadHuffmanFile(){
ifstream fin;
char filename[30];
char a;
int i=0;
system("cls");
cerr<<"/n/n/t请输入要显示的霍夫曼编码文件名称:";
cin>>filename;
sprintf(filename,"%s%s",filename,".txt");
fin.open(filename);
fin>>a;
while(!fin.eof()){
if(a!='1'&&a!='0'){
cout<<"/n/n/t这文件不是霍夫曼编码文件,按任意键退出"<<endl;
getch();
return false;
}
cout<<a;
i++;
if(i>70){
cout<<endl;
i=0;
}
fin>>a;
}
cout<<"/n/n/t文件显示完成,按任意键确定"<<endl;
getch();
return true;
}
//************************************************************
void main(){
while(1){
system("cls");
cout<<"/n/n/t请选择操作代码:"
<<"/n/n/t1: 文本文件转换为霍夫曼代码"
<<"/n/n/t2: 霍夫曼代码转换为原文件"
<<"/n/n/t3: 显示源文件"
<<"/n/n/t4: 显示霍夫曼编码文件"
<<"/n/n/t 退出程序请按Esc键"
<<endl;
switch(getch()){
case '1':
if(textconvertohuffman())
cout<<"/n/t文件转换完成/n/n/t按任意键确定"<<endl;
else
cout<<"/n/t文件转换出错!!!/n/n/t按任意键确定"<<endl;
getch();
break;
case '2':
if(huffmanconvertotext())
cout<<"/n/t文件转换完成/n/n/t按任意键确定"<<endl;
else
cout<<"/n/t文件转换出错!!!/n/n/t按任意键确定"<<endl;
getch();
break;
case '3':if(!Readfile()){
cout<<"/n/n/t程序执行出错,按任意键确定"<<endl;
getch();
}
break;
case '4':if(!ReadHuffmanFile()){
cout<<"/n/n/t程序执行出错,按任意键确定"<<endl;
getch();
}
break;
case 27:return ;
default:cout<<"/n/n/t输入错误,按任意键重试"<<endl;
getch();break;
}
}
}
bool huffmantree::DestoryHuffman()
{
if(!root)
return false;
BSTNode *temp1=root,*temp2=root->rightchild;
while(temp2){
delete temp1->leftchild;
delete temp1;
temp1=temp2;temp2=temp2->rightchild;
}
delete temp2;
root=NULL;
return true;
}
void BST::Destory()
{
BSTNode *temp=root,*temp1;
if(!root)
return ;
while(temp->leftchild)//找第一个的节点,因为是线索化的
temp=temp->leftchild;
while(temp){
temp1=temp;
if(temp->Threaded)//如果当前节点已线索化
temp=temp->rightchild;
else{//当前节点没有线索化
temp=temp->rightchild;
while(temp&&temp->leftchild)//找最左边的节点
temp=temp->leftchild;
}
delete temp1;
}
root=NULL;
return ;
}
相关推荐
霍夫曼树编码和解码是数据结构领域中一种高效的数据压缩方法,主要应用于文本压缩。霍夫曼编码是基于频率的变长编码,通过构建一棵特殊的二叉树——霍夫曼树(又称为最优二叉树或最小带权路径长度树)来实现。在...
霍夫曼树,又称最优二叉树或最小带权路径长度树,是一种特殊的二叉树,主要用于数据编码,包括压缩和解压缩。在文件压缩领域,霍夫曼编码是一种常用的无损数据压缩方法,它利用字符出现频率进行编码,频率高的字符用...
在IT领域,数据结构是计算机科学的基础,而霍夫曼树和堆排序是两种非常重要的数据结构和算法。本文将详细解析这两个概念及其在C++中的实现。 首先,让我们了解霍夫曼树(Huffman Tree),它是一种特殊的二叉树,也...
霍夫曼树(Huffman Tree),也称为最优二叉树,是数据压缩技术中的关键工具,主要用于构建霍夫曼编码。这种编码方法基于字符出现频率,频繁出现的字符赋予较短的编码,不常出现的字符则赋予较长的编码,以此达到数据...
利用最小堆编程实现给定权值集合下构造相应霍夫曼树的算法,并解决以下问题: 有一电文共使用五种字符a,b,c,d,e,其出现频率依次为4,7,5,2,9。 (1)构造对应的编码哈夫曼树(要求左子树根结点的权小于等于右子树根结点...
2. **生成霍夫曼编码**:从霍夫曼树的根节点出发,左分支代表0,右分支代表1,沿着路径到达每个叶子节点(表示字符)时,记录下路径上的0和1,就得到了该字符的霍夫曼编码。 3. **编码过程**:对原始文本中的每个...
从给定的文件信息来看,该段代码主要涉及到了数据结构中的两个重要概念:霍夫曼树(Huffman Tree)和二叉搜索树(Binary Search Tree),并使用C++语言进行实现。以下是对这两个知识点的详细解析: ### 霍夫曼树...
霍夫曼树数据结构课程设计 霍夫曼树是一种特殊的二叉树数据结构,广泛应用于数据压缩领域。它的主要特点是使用_variable-length prefix codes_,即符号的编码长度与其出现频率成反比。霍夫曼树的构建过程将字符的...
### 题目解析:用C++实现霍夫曼树编码 #### 霍夫曼编码简介 霍夫曼编码是一种广泛应用于数据压缩领域的编码方式,由David A. Huffman于1952年提出。其核心思想是为高频出现的数据分配较短的编码,而低频出现的数据...
根据给定的信息,本文将详细解释“霍夫曼树代码”的相关知识点,包括霍夫曼树的基本概念、霍夫曼编码的应用以及通过示例代码理解霍夫曼树的构建过程。 ### 霍夫曼树简介 霍夫曼树(Huffman Tree),也称为最优...
霍夫曼树是一种特殊的二叉树,也称为最优二叉树或最小带权路径长度(Minimum Weight Path Length, MWPL)树。它在数据压缩、字符编码等领域有广泛应用,特别是霍夫曼编码,是实现数据压缩的一种高效方法。 霍夫曼树...
霍夫曼树,又称最优二叉树或最小带权路径长度树,是数据结构中一种特殊的二叉树,常用于数据的压缩编码。在霍夫曼树中,频率较高的字符对应的树节点通常离根节点更近,从而实现高效的数据编码。这种编码方式被称为...
霍夫曼树,又称最优二叉树或最小带权路径长度树,是一种特殊的二叉树结构,常用于数据编码和压缩。在C语言中实现霍夫曼树涉及到数据结构、算法以及文件操作等多个IT领域的知识。 首先,我们需要理解霍夫曼树的基本...
C语言写的 霍夫曼树的算法C语言写的 霍夫曼树的算法C语言写的 霍夫曼树的算法C语言写的 霍夫曼树的算法
霍夫曼树,又称最优二叉树或最小带权路径长度树,是一种特殊的二叉树,主要用于数据编码,特别是文本压缩。在文本压缩领域,霍夫曼编码是一种高效的无损压缩方法,它依据字符出现频率来分配编码,频繁出现的字符对应...
2. 构建霍夫曼树:根据字符频率,按照霍夫曼树的构建规则创建树结构。 3. 生成编码表:遍历霍夫曼树,为每个叶子节点生成对应的霍夫曼编码。 4. 对输入字符串进行编码:使用生成的编码表,将输入字符串转换为霍夫曼...
### 霍夫曼树——创建霍夫曼树及其部分应用 #### 一、霍夫曼树概述 霍夫曼树(Huffman Tree),又称最优二叉树,是一种带权路径长度最短的二叉树,在数据压缩领域有着广泛的应用。它的主要应用场景包括但不限于...
### 霍夫曼树——数据结构 #### 知识点概述 霍夫曼树(Huffman Tree),又称最优二叉树,是一种带权路径长度最短的二叉树,即对应叶子结点的权值乘以其到根结点之间的路径长度之和最小。霍夫曼树在数据压缩、编码...
霍夫曼树是一种特殊的二叉树,主要用于数据的压缩,特别是在文本编码中。它通过构建一个具有最小带权路径长度的二叉树来达到高效的数据编码。在霍夫曼树中,频率较高的字符对应的二进制编码较短,反之则较长,这有助...
霍夫曼树(Huffman Tree),也称为最优二叉树,是一种特殊的二叉树,用于数据编码,特别是在数据压缩领域有着广泛的应用。它的构造原则是:具有最小带权路径长度的二叉树被称为霍夫曼树,即在该树中,从根节点到每个...