实验三二叉树操作Word文档格式.docx
《实验三二叉树操作Word文档格式.docx》由会员分享,可在线阅读,更多相关《实验三二叉树操作Word文档格式.docx(20页珍藏版)》请在冰豆网上搜索。
![实验三二叉树操作Word文档格式.docx](https://file1.bdocx.com/fileroot1/2023-1/4/99b76521-4c16-4526-8a8a-18b6a48c3ac8/99b76521-4c16-4526-8a8a-18b6a48c3ac81.gif)
教师签字:
考核内容
评价在实验课堂中的表现,包括实验态度、编写程序过程等内容等。
□功能完善,
□功能不全
□有小错
□无法运行
○正确
○基本正确
○有提示
○无法回答
○完整
○较完整
○一般
○内容极少
○无报告
○有
○无
一、实验目的
理解二叉树的逻辑特点和二叉树的性质;
掌握二叉树的二叉链表存储结构,掌握二叉树的创建算法、遍历算法的递归与非递归实现,并能在遍历算法基础上实现较复杂算法设计。
二、实验题目与要求
1.每位同学按下述要求实现相应算法:
以二叉链表为存储结构,实现二叉树的创建、遍历算法
1)问题描述:
在主程序中提供下列菜单:
1…建立树
2…前序遍历树
3…中序(非递归)遍历树
4…后序遍历树0…结束
2)实验要求:
①定义下列过程:
CreateTree():
按从键盘输入的前序序列,创建树
PreOrderTree():
前序遍历树(递归)
InOrderTree():
中序(非递归)遍历树
LaOrderTree():
后序遍历树(递归)
②每位同学在实验过程中要单步运行程序,跟踪二叉树的创建过程与前序遍历的递归过程。
3)注意问题:
①注意理解递归算法的执行步骤。
②注意字符类型数据在输入时的处理。
③重点理解如何利用栈结构实现非递归算
2.编写算法交换二叉树中所有结点的左、右子树
编写一算法,交换二叉树中所有结点的左、右子树
以二叉链表作为存储结构
3.试编写按层次顺序遍历二叉树的算法
编写按层次顺序遍历二叉树的算法
4.编写算法求二叉树高度及宽度。
1)问题描述:
二叉树高度是指树中所有节点的最大层数,二叉树宽度是指在二叉树的各层上,具有节点数最多的那一层上的节点总数。
2)实验要求:
三、实验过程与实验结果
应包括如下主要内容:
Ø
数据结构定义
二叉树是个节点的有限集合,该集合或者为空,或者由一个根节点及两个分别称为左子树和右子树的互不相交的二叉树组成。
当集合为空时,称该二叉树为空二叉树。
算法设计思路简介
1、利用递归算法前序建立二叉树,并完成二叉树的前序、中序和后序遍历。
其中前序遍历和后序遍历均用递归算法,中序遍历借助栈的机制,实现非递归遍历。
2、在前序遍历的过程中利用中间变量交换左右子树。
3、利用队列。
当上一层中的数据全部出队(遍历)完毕再遍历本层节点。
4、高度:
获取所有节点到根节点的最长路径。
宽度:
在层次遍历的基础上,返回最多节点的层的节点数。
算法描述:
可以用自然语言、伪代码或流程图等方式
1、创建树:
(1)声明节点
(2)输入当前节点,若输入为#则当前节点为空,否则为当前节点申请空间。
(3)将输入的值赋给当前节点的data域,并前序建立当前节点的左子树和右子树。
(4)返回当前节点。
前序遍历树:
(1)若当前节点为空则返回上一级函数,否则打印当前节点。
(2)前序遍历当前节点的左子树。
(3)前序遍历当前节点的右子树。
中序遍历树:
(1)声明一个顺序栈,并用p指针指向当前节点。
(2)若当前节点和栈不同时为空则重复进行下一步。
否则程序结束
(3)若当前节点不为空则重复进行第四步,否则执行第五步。
(4)在栈不满的情况下将当前节点入栈,并把p指针指向当前节点左子树的根节点。
(5)若栈为空则执行第三步,否则执行第六步。
(6)将栈顶元素出栈,并打印栈顶元素的data,将p指向栈顶元素的右子树的根节点。
执行第二步。
(1)若当前节点为空则返回上一级函数否则执行下一步。
(2)后序遍历当前节点的左子树。
(3)后序遍历当前节点的右子树。
(3)打印当前节点的data。
2、
(1)若当前节点为空则返回NULL,结束。
否则执行下一步。
(2)利用中间变量temp交换当前节点的左右子树。
(3)交换当前的点左子树根节点的左右子树。
(4)交换当前节点右子树根节点的左右子树。
(4)返回根节点。
3、
(1)利用指针temp指向根节点,并初始化一个队列。
(2)将temp指向的当点节点入队。
(3)重复指向以下所有步骤,直到遇到break语句。
(4)用变量len记录队列中二叉树当前层的节点数。
(5)若len为0则结束整个程序,否则执行第六步。
(6)当len>
0(即队列中还有前层的节点时)重复指向以下所有步骤。
否则执行第三步。
(7)将当前对头出栈,len++,打印出队元素
(8)如果出队元素的左子树的根节点不为空则入队,len--.
(9)如果出队元素的右子树的根节点不为空则入队,len--.
4、
并声明当前层最大节点数为0
若遇到break语句则结束整个程序并返回最大节点数。
0(即队列中还有前层的节点时)重复七~九步。
否则执行第十步。
(10)当前层最大节点数等于上一层最大节点数和当前队列中的节点数中较大的一个。
执行第三步。
算法的实现和测试结果:
包括算法运行时的输入、输出,实验中出现的问题及解决办法等
1、
输入:
ABH##FD###E#CK##G##
输出:
☐
☐3、
☐输出:
算法时间复杂度分析
1、O(n).
2、O(n).
3、O(n).
4、O(n).
四、收获与体会
学了二叉树之后顿时感觉之前的内容有多简单了。
二叉树中用到很多递归算法,看起来很难懂。
需要一步一步的跟下去才能理解,但是理解还远远不够,关键是是自己能写出来属于自己的递归算法。
经过长时间的练习,我已经能写出来一些简单的递归算法了,但是稍微难一点的就写不出来了。
后面的图还更难。
革命尚未成功,诸君还需努力呐。
我相信经过自己不屑的练习,我会提高的!
五、源代码清单
#include<
stdio.h>
stdlib.h>
#defineMaxSize100
typedefcharElemtype;
typedefstructBitNode
{
Elemtypedata;
structBitNode*lchild;
structBitNode*rchild;
}BitNode;
BitNode*CreateTree()
charch;
BitNode*T;
scanf("
%c"
&
ch);
if(ch=='
#'
)T=NULL;
else{if(!
(T=(BitNode*)malloc(sizeof(BitNode))))
exit
(1);
T->
data=ch;
lchild=CreateTree();
rchild=CreateTree();
}
returnT;
}
voidPreOrder(BitNode*T)
if(T==NULL)return;
printf("
T->
data);
PreOrder(T->
lchild);
rchild);
voidPostOrder(BitNode*T)
PostOrder(T->
voidInOrder(BitNode*T)
BitNode*p,*q;
BitNode*Stack[MaxSize];
inttop=0;
p=T;
while(!
(p==NULL&
&
top==0))
{
while(p!
=NULL)
{
if(top<
MaxSize-1)
{
Stack[top]=p;
top++;
}else{
printf("
栈溢出"
);
exit(0);
}
p=p->
lchild;
}
if(top<
=0)return;
top--;
p=Stack[top];
printf("
p->
p=p->
rchild;
intmain()
BitNode*root;
root=CreateTree();
前序遍历结果"
PreOrder(root);
\n"
中序遍历结果"
InOrder(root);
后序遍历结果"
PostOrder(root);
return0;
typedefstructBitTree
structBitTree*lchild;
structBitTree*rchild;
}BitTree;
BitTree*CreateTree()
BitTree*T;
else{
T=(BitTree*)malloc(sizeof(BitTree));
voidInOrder(BitTree*T)
InOrder(T->
BitTree*Exchange(BitTree*T)
BitTree*temp;
if(T==NULL)returnNULL;
temp=T->
T->
lchild=T->
rchild=temp;
Exchange(T->
BitTree*root;
中序遍历原二叉树:
"
root=Exchange(root);
\n中序遍历交换后的二叉树:
typedefBitTreeElementtype;
typedefstructQueueNode
Elementtype*base;
intfront;
intrear;
}QueueNode;
/*以上为树*/
QueueNode*InitQueue()
QueueNode*Q;
Q=(QueueNode*)malloc(sizeof(QueueNode));
Q->
base=(Elementtype*)malloc(MaxSize*sizeof(Elementtype));
rear=Q->
front=0;
returnQ;
intQueueFull(QueueNode*Q)
if((Q->
rear+1)%MaxSize==Q->
front)return1;
elsereturn0;
intQueueEmpty(QueueNode*Q)
if(Q->
rear==Q->
QueueNode*Push(QueueNode*Q,Elementtype*ele)
if(QueueFull(Q))
队列已满,无法入队!
}else{
*(Q->
base+Q->
rear)=*ele;
Q->
rear=(Q->
rear+1)%MaxSize;
QueueNode*Pop(QueueNode*Q,Elementtype*ele)
if(QueueEmpty(Q))
队列为空,无法出队"
*ele=*(Q->
base+Q->
front);
front=(Q->
front+1)%MaxSize;
voiddisplay(BitTree*T)
Elementtypeelem;
temp=T;
QueueNode*queue;
queue=InitQueue();
queue=Push(queue,temp);
do
queue=Pop(queue,&
elem);
temp=&
elem;
temp->
if(temp->
lchild!
queue=Push(queue,temp->
rchild!
}while(!
QueueEmpty(queue));
/*以上为队列*/
display(root);
intGetLength(QueueNode*Q)
inti=Q->
front;
intj=1;
while(i!
=Q->
rear)
i=(i+1)%MaxSize;
j++;
return(j-1);
队列为空,无法出队!
intGetHeight(BitTree*T)
if(T==NULL)return0;
intLeftHeight=GetHeight(T->
intRightHeight=GetHeight(T->
returnLeftHeight>
RightHeight?
(LeftHeight+1):
(RightHeight+1);
intGetWidth(BitTree*T)
intMaxWidth=0;
queue=Push(queue,T);
while
(1)
intlen=GetLength(queue);
if(len==0)
break;
while(len>
0)
queue=Pop(queue,&
len--;
temp=&
if(temp->
queue=Push(queue,temp->
MaxWidth=MaxWidth>
GetLength(queue)?
MaxWidth:
GetLength(queue);
returnMaxWidth;
%d%d"
GetHeight(root),GetWidth(root));