一、实验目的
- 掌握二叉树的建立和遍历
- 掌握二叉树遍历的应用
- 掌握线索二叉树的建立和遍历
- 掌握hufmman编码
二、实验内容
- 递归建立和层次遍历二叉树
- 二叉树的深度非递归遍历
- 统计二叉树中右孩子节点的个数
- 线索二叉树的建立和遍历
- 哈夫曼编码
三、实验环境
在PTA平台进行实验
四、实验要求
根据每个实训的要求完成代码提交和测评
五、实验步骤
描述算法的原理或实现流程(测评完全正确或部分正确的实训)
6-1 递归建立和层次遍历二叉树
本题要求编写建立二叉树的函数和层次遍历二叉树的函数
1. 建立二叉树:用先序遍历的方式,输入的是扩展二叉树,当输入#时,指针指向NULL,说明是叶结点,否则一直递归下去
2.层次遍历二叉树
创建空队列LinkQueue queue=SetNullQueue_Link();
根结点不为空,根结点入队EnQueue_link(queue,bt);
队列不空,循环执行操作while(!IsNullQueue_Link(queue))
去队头元素,出队;
左、右孩子不空,则入队。
7-1 非递归方式统计二叉树中右孩子结点的个数
本题要求采用非递归方式统计二叉树中右孩子结点的个数。
输入格式:这里采用递归方式建立二叉树,输入的先序序列
输出格式:输出是二叉树右孩子结点的个数
非递归遍历二叉树:从根结点bt开始,将根结点压入栈lstack中;如果栈lstack不空,从栈lstack中弹出一个元素p,并访问;如果p的右孩子不为空,入栈;如果p的左孩子不为空,入栈;重复一直到栈为空为止
统计右孩子的数目:先序遍历的顺序为根-左-右,先把右节点入栈,再把左结点入栈。当遍历到的结点的右结点不为空时,将右孩子的数目加一
7-2 二叉树的非递归遍历
本题要求采用栈实现对二叉树的非递归遍历,包括先序、中序和后序三种遍历方式。
输入格式:输入序列是按照先序序列输入,以@表示空结点
输出格式:先序、中序和后序遍历序列分别按行输出
先序遍历:从根节点开始,将根节点入栈。检查栈,若栈不空,出栈,先访问左孩子,左孩子不为空则输出,再检查右孩子,有右孩子则入栈,再继续访问左分支。若左孩子为空,检查栈,若栈不空,弹出元素,继续递归。若都为空,结束遍历
中序遍历:从根节点开始,沿着左分支一直深入将结过的每一个结点入栈,直到到达一个空结点。然后出栈一遍历素,并访问出栈的元素,接着进入出栈结点的右分支,此时检查出栈结点的右分支以及栈是否为空,如果都为空算法结束,否则重复上述过程
后序遍历:
如果左分支不空,则沿着左分支一直下行,经过的结点进栈,直到沿着左分支深入不下去时检查右分支,如果右分支不为空,接着进入右分支。重复上述过程。直到一个结点的左右都为空时访问该结点,记为Now。如果Now是父结点的左孩子,则继续进入父结点的右分支,重复上述步骤。如果Now是父结点的右孩子,则说明父结点的左右结点均已经处理,返回上级的根结点,出栈访问。当Now为空且栈也为空时结束
7-3 线索二叉树的建立和遍历
本题要求实现对建立中序线索二叉树和中序遍历中序线索二叉树。
输入格式:输入为先序序列
输出格式:输出为中序遍历线索树的结点值以及结点的左右指针信息。
建立中序线索二叉树:
创建两个指针p和pr,pr为前驱p为当前结点。中序遍历二叉树,如果左子孩子不空,左标志位不变(依旧为0),左指针指向下一个结点。左孩子空,则将左指针指向前驱结点,即pr指向的结点,并把左标志位修改为1。右子树同左子树一样,但是有没有右孩子的时候将右指针指向后继结点,并把右标志位修改为1.
中序遍历线索二叉树:
在中序遍历的第一个结点是沿着左分支的最下面的结点;在线索二叉树中,一个结点的后继分为两种情况;
如果该结点的右标志位是线索,则右指针指向该结点的后继结点;如果该结点的右标志位不是线索,则右指针指向该结点的右子树的根结点,根据中序遍历的定义,该结点的后继是右子树的最左下结点。
7-4 哈夫曼编码
本题要求字符的哈夫曼编码,注意建立的哈夫曼树严格按照左小右次小的顺序,并且哈夫曼编码时严格按照左‘0’右‘1’进行编码。
输入格式:输入是各个字符在通信中出现的频率
输出格式:输出是各个字符的哈夫曼编码,每个字母占一行
采用顺序存储,根据扩充二叉树的性质,如果有n个外部结点,则右n-1个内部结点,总结点个数为2n-1,故此的数组大小为2n-1。
分配2n-1大小的数组空间;存放n个外部结点和n-1个内部结点,设置parent为-1,设置左孩子为-1,设置右孩子为-1。对于外部结点,weight为权值大小,对于内部结点,设置weight为-1;
找到权值最小和次小的元素,并根据这两个结点构造父结点;
令父结点的权值是最小和次小结点的权值之和,父结点和左孩子即x1的数组下标,父结点的右孩子即x2的数组下标;
对于最小和次小的元素,修改其parent为新生成的父结点的数组下标。
六、问题记录和实验总结(必写)
二叉树的基本知识就是先序、中序、后续建立及遍历,必须熟练掌握才能进行后续操作。二叉树与树、树林,哈夫曼编码、线索二叉树、二叉树的递归与非递归建立与遍历、统计叶子节点的个数,等等等等都是二叉树应该掌握的内容。