文章导航
大二上数据结构实验1内容,使用C语言实现树的遍历操作及基于霍夫曼树的编码/译码
一、实验题目和要求
实验题目:树的遍历操作及基于霍夫曼树的编码/译码 (一)实验目的:掌握结构体、指针及二叉树的生成、遍历等操作,掌握霍夫曼编码/译码的原理。 (二)基本要求:熟练掌握树的操作。 (三)内容提要: 1)通过键盘输入一段字符(长度>=20),构建霍夫曼树; 2)根据该树求每个字符的编码,并对该段字符串进行编码; 3)将得到的编码进行译码; 4)基于该霍夫曼树,实现非递归的先序遍历算法,输出该树所有的节点、节点的权值、节点的度和节点所在的层数; 5)基于该霍夫曼树,实现基于队列的层序遍历算法,输出该树所有的节点、节点的权值、节点的度和节点所在的层数。
注:在实现时要求霍夫曼树的左右孩子的大小关系满足,左孩子节点权值小于右孩子节点权值。
二、按不同功能分析各程序模块
(一)包含库函数、定义常量、变量类型
1 |
(二)构建哈夫曼树、栈、队列的结构、操作
1 | typedef struct HTNode//哈夫曼树 |
(三)构建哈夫曼树、求编码
1 | void Select(HuffmanTree HT,int n,int *s1,int *s2)//选择两个最小结点 |
(四)编码、解码
1 | int getcode(HuffmanCode &code,char* str,HuffmanCode HC,char* word)//编码 |
(五)两种遍历
1 | void Depth(HuffmanTree T)//求哈夫曼树节点的深度(所在层数) |
(六)主函数
1 | int main() |
三、思路分析
- 在本实验中,使用getchar()从键盘输入一个字符串,建立一个长度为128的数组(用于对应ASCII码表),用于存储记录每个字符出现的次数,利用循环即可得到,用word数组存储所有出现的字符,并且将其一一对应到存储节点权值的数组weight中
- 利用子函数HuffmanCoding()构建哈夫曼树。先将n个节点分别对应到n个字符上,令其权值为字符出现的次数。用select()函数每次取出权值最小的两个节点,将其权值相加,作为父节点的权值,小的为左子节点,大的为右子节点。求编码时,由叶子节点向上回溯,如果为左子节点,就为0,否则为1。编码为其倒序输出。
- 将求得的编码和字符一一对应即可得到编码与解码
- 先序遍历时,先将根节点压栈,当栈非空时,执行循环:弹出p,访问p指针指向的节点,如果p节点左孩子指针非空,将左孩子压栈,如何p节点右孩子指针非空,将右孩子压栈。即可实现非递归的先序遍历。
- 层序遍历时,先将根节点入队,访问根节点,当队列非空或p指针非空时,执行循环:如果p的左孩子指针非空,将p的左孩子入队,如果p的右孩子指针非空,将p的右孩子入队,将队列尾节点退队。即可实现非递归的层序遍历。 Ps:select函数:用两个循环分别找到权值数组中最小的两个值,用一个判断保证s1<s2。 visit函数:用一个判断保证当节点度数为0是为字符,依据其编码确定是哪个字符;否则不是字符。再输出节点的度数、深度、权值。
四、运行结果分析
随便输入一组字符运行结果如下:
根据画图分析,运行结果正确。