没有合适的资源?快使用搜索试试~ 我知道了~
实验四 树和二叉树及其应用(I).pdf
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 187 浏览量
2022-11-12
11:45:19
上传
评论
收藏 594KB PDF 举报
温馨提示
试读
13页
。。。
资源推荐
资源详情
资源评论
姓名 学号
实
验
树和二叉树及其应用(I)
项
目
实
验
内
容
算法设计与程序实现:
算
法
分
析
本 次 实 验 主 函 数 采 用 顺 序 结 构 , 主 函 数 调 用 自 己 编 写 的 头 文 件
DataStructure_BinaryTree.h
中的相关功能函数,完成实验要求。
程序实现:
1、二叉树的遍历:实验分别递归与非递归的方法分别进行了先序、中序、后
序和层序遍历。由于先序、中序、后序的递归遍历实现算法非常类似,所以以下的算
法具体实现只对递归的先序遍历和层序遍历以及非递归的先序遍历、后序遍历和层序
遍历作详细的分析说明。
2、二叉树的基本操作:
(1) 求二叉树的深度;
(2) 求二叉树中叶子结点的个数;
(3) 先序交换二叉树;
(4) 查找以指定元素值为的根节点的根子树;
(5) 删除以指定元素值为的根节点的根子树;
(6) 判断二叉树是否为完全二叉树。
以下分别以上的基本操作算法的具体实现作了详细的分析说明。
1、二叉树的遍历
递归先序遍历:先序遍历二叉树的原则是当二叉树不为空时,先访问根结点,再
次先序遍历左子树,最后先序遍历右子树,否则进行空操作(递归结束的条件)。
按照以上先序遍历的原则,采取递归的方法很容易完成程序的具体实现。
递归层序遍历:层序遍历顾名思义从根结点出发从左到右逐层进行访问,由此可
以通过控制层次数进而进行逐层遍历,当层次数不为零时,层次数递减递归遍历
左、右子树,当层次数为零时(递归结束条件),访问该节点。遍历时可不比事先
知道二叉树的深度 (用于层次数递增边界控制 ),当当前层次数下访问失败并返
回,则当前层次数即为二叉树的深度。以上遍历中对每一层遍历都需从根结点出
1
1.建立二叉树的二叉链表存储结构,实现二叉树的前序、中序、后序递归遍历。
二叉链表存储结构定义参见教材第 127 页。
遍历算法参见教材第 128-129 页。
2.编写递归算法,计算二叉树中叶子结点的数目。(题集第 42 页 6.42)
3.编写递归算法,计算二叉树的深度。(题集第 43 页 6.44)
发。
非递归先序遍历:在根指针不空的情况下,访问根结点,根指针域压栈,继续遍
历左子树,循环上诉操作,当左子树指针为空(循环结束条件,同时也是遍历右
子树的条件),此时表明根指针已空, 本左子树遍历完毕,然后退栈返回上一层,
弹出的指针即此时根结点指针,继续遍历右子树未曾访问的结点。
非递归中序遍历:如同此法,中序与先序的不同是不能首先访问根结点,而是要
先访问作孩子节点,要使根结点能够被访问,就要求此时根结点的左孩子为空,
这样根结点就能访问了,故访问操作是在根指针退栈后进行访问的。
非递归后序遍历:后序遍历与上面的先序、中序遍历的不同是也访问根结点的条
件,即当根结点的右指针域为空或右孩子指针指向的节点已被访问过。由此算法
是只要根指针不空时,将根指针进栈,遍历左子树,当根指针为空 (根节点的左
孩子指针为空,该指针并没有进栈),取出栈顶指针,判断右孩子指针是否为空
或已被访问过,如果上述条件成立则访问根结点,退栈并更新用于记录被访问的
指针。
非递归层序遍历:根据二叉树的特性,使用队列这种数据结构,出队列一个节点
指针,入队列两个节点指针,出队列指针结点的左右孩子指针即为入队列的指针
(当访问成功才入队列),通过上述操作即可实现层序遍历。
2、二叉树的基本操作
求二叉树的深度:求二叉树的深度即求得左右子树的深度(左右子树深度最大值)
加 1,当然求左右子树的深度即求左右子树的左右子树的深度加 1,由此递归下
去,当子树为空时(递归结束条件),返回 0,然后逐层向上其的二叉树深度。
求二叉树中叶子结点的个数:叶子结点即左右子树皆为空的节点。由此选择递归
就很容易实现,从根结点开始进行遍历,判断当前结点的左右子树是否为空,不
为空则继续访问下一个节点,为空则使叶子结点数加 1,继续查找其他的节点。
先序交换二叉树:当根指针不空时,交换左右子树指针,然后交换左子树的左右
孩子指针,如此递归操作,当当前的根指针为空时,返回,交换右子树,如此就
完成了二叉树的交换。
查找以指定元素值为的根节点的根子树:查找根遍历是相同的,只是把遍历的具
体应用函数改为判断访问的节点的数据是否等于指定的数据,当找到则返回当前
节点的根指针,若全部访问结束都还没栈顶则返回失败。
删除以指定元素值为的根节点的根子树:查找指定元素的操作可通过上诉函数完
成,至此只需要调用删除二叉树函数,至于删除二叉树的算法是当根指针不空时,
依次释放左右子树的内存,然后释放根结点,当然释放左右子树时又是先释放左
右子树的左右子树的内存,如此进行递归操作,当根指针为空时,返回。
判断二叉树是否为完全二叉树:判断二叉树是否为完全二叉树可以转化为判断二
叉树的左右子树的深度是否相等,当相等时,二叉树即为完全二叉树,不等则不
是完全二叉树。当然判断二叉树的深度是递归进行的,最终是判断二叉树的最底
层的左右子树深度是否为零。
核
心
程
此程序中用到的自己编写的头文件以在下面给出,而头文件的说明则在主函数中
文件包含部分的注释处,核心程序如下:
1.主函数如下:
#include "iostream" //标准输入输出流库文件
#include "windows.h" //cmd窗口设置函数头文件
#include "ADT.h" //数据结构中相关结构体类型定义及相关数据类型定义
2
序
#include "DataStructure_BinaryTree.h" //数据结构第六章树与二叉树函数的定义及声明
using namespace std;
int main(void)
{
system("title 数据结构实验 实验四:树和二叉树及其应用(I) "); //设置cmd窗口标题
system("color F1"); //设置控制台窗口的背景色和前景色
system("date /T"); //输出当前的日期
print();
cout << "实验内容一: 树的遍历" << endl;
BiTree T;
int num = 0;
cout << " 二叉树的建立:" << endl;
cout << " 输入二叉树数据:";
GreateBiTree(T); //先序建立二叉树
cout << " 二叉树的遍历" << endl << " 【递归遍历】 ";
cout << endl << "> 先序遍历:";
PreOrderTraverse(T, PrintElement); //先序遍历二叉树
cout << endl << "> 中序遍历:";
InOrderTraverse(T, PrintElement); //中序遍历二叉树
cout << endl << "> 后序遍历:";
PostOrderTraverse(T, PrintElement); //后序遍历二叉树
cout << endl << "> 层序遍历:" << endl;
LevelOrderTraverse(T, PrintElement); //层序遍历二叉树
cout << endl<< " 【非递归遍历】";
cout << endl << "> 先序遍历:";
PreOrderTraverseNonRec(T, PrintElement); //先序遍历二叉树
cout << endl << "> 中序遍历:";
InOrderTraverseNonRec(T, PrintElement); //中序遍历二叉树
cout << endl << "> 后序遍历:";
PostOrderTraverseNonRec(T, PrintElement); //后序遍历二叉树
cout << endl << "> 层序遍历:";
LevelOrderTraverseNonRec(T, PrintElement);//层序遍历二叉树
print();
cout << endl << "实验内容二:二叉树的基本操作";
cout << endl << "<1> 二叉树的深度:" << BiTDepth(T) << endl;
LeafTNodeNum(T, num);
cout << "<2> 二叉树中叶子结点的数目:" << num << endl;
cout << "<3> 交换左右子树:" << endl;
ExchangeBiTree(T);
cout << " 交换后的二叉树:" << endl;
LevelOrderTraverse(T, PrintElement); //层序遍历二叉树
BiTree root;
TElemType x;
3
剩余12页未读,继续阅读
资源评论
春哥111
- 粉丝: 1w+
- 资源: 5万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功