二叉树的简单操作.docx
《二叉树的简单操作.docx》由会员分享,可在线阅读,更多相关《二叉树的简单操作.docx(19页珍藏版)》请在冰豆网上搜索。
![二叉树的简单操作.docx](https://file1.bdocx.com/fileroot1/2023-6/27/fabba73f-9506-4f3e-aa55-7e9a2b6abd6b/fabba73f-9506-4f3e-aa55-7e9a2b6abd6b1.gif)
二叉树的简单操作
实验3二叉树的遍历
成绩
专业班级信息131班学号201312030120姓名******报告日期2015.11.25
实验类型:
●验证性实验○综合性实验○设计性实验
实验目的或任务
通过指导学生上机实践,对常用数据结构的基本概念及其不同的实现方法的理论得到进一步的掌握,并对在不同存储结构上实现不同的运算方式和技巧有所体会。
实验教学基本要求
1.了解实验目的及实验原理;
2.编写程序,并附上程序代码和结果图;
3.总结在编程过程中遇到的问题、解决办法和收获。
实验教学的内容或要求
1.编写函数,输入字符序列,建立二叉树的二叉链表
2.编写函数,实现二叉树的中序递归遍历算法。
3.编写函数,实现二叉树的中序非递归遍历算法
4.编写函数,借助队列实现二叉树的层次遍历算法
5.编写函数,求二叉树的高度
6.编写函数,求二叉树的结点个数
7.编写函数,求二叉树的叶子个数
8.编写函数,交换二叉树每个结点的左子树和右子树
9.编写一个主函数,在主函数中设计一个简单的菜单,分别调试上述算法
实验开出要求
必做
实验所需仪器设备
1.计算机
2.相关软件(如C,C++,PASCAL,VC,DELPHI等等)
实验所用材料
计算机耗材
一、实验效果图
1.编写函数,输入字符序列,建立二叉树的二叉链表
2.编写函数,实现二叉树的中序递归遍历算法。
3.编写函数,实现二叉树的中序非递归遍历算法
4.编写函数,借助队列实现二叉树的层次遍历算法
5.编写函数,求二叉树的高度
6.编写函数,求二叉树的结点个数
7.编写函数,求二叉树的叶子个数
8.编写函数,交换二叉树每个结点的左子树和右子树
二、实验总结
通过这次实验报告,我学会了如何利用链表来存储二叉树,利用先序遍历来建立二叉树,在其中还学会二叉树的中序递归遍历和利用栈消除递归的中序非递归遍历以及利用队列的层次遍历。
掌握了如何利用递归遍历求取二叉树的结点个数以及叶子结点的个数。
在实验的最后训练了我如何交换二叉树的两个子树。
在单链表和栈与队列的基础上,这次实验报告有了很大的提高,无论是在程序的可读性行还是程序的通用性上。
例如将不同的程序放到了不同的源文件里边,使得程序的结构更加清晰。
但是其中仍有不足,绝大多的函数实现都是通过递归来解决的,虽然可读性较高,但效率比较差,耗费的时间比较长,需要进一步的努力。
在接下里的学习中,我会更加努力,在学好算法的基础上不断地提高自己的编程能力和逻辑思维能力。
三、程序代码
#define_CRT_SECURE_NO_WARNINGS
#definem100
#defineQueue_Size100
typedefcharDataType;
typedefstructNode/*二叉链表的结构体*/
{
DataTypedata;
structNode*LChild;
structNode*RChild;
}BiTNode,*BiTree;
typedefBiTreeQueueElement;
typedefstruct//定义顺序队列的结构体
{
QueueElementelem[Queue_Size];//存放队列元素的一维数组
inttop;//用来存放队列元素的下标,top=-1表示空队
}SeqQueue;
BiTreeCreateBiTree(void);//创建二叉链表
voidInOrder(BiTreeroot);//中序递归遍历二叉树
voidinoeder(BiTreeroot);//中序非递归遍历二叉树
intLayerOrder(BiTreebt);/*层次遍历二叉树*/
intPostTreeDepth(BiTreebt);/*后序遍历二叉树求高度的递归算法*/
intleaf(BiTreeroot);/*后序遍历统计叶子结点的个数*/
intPreOrder(BiTreeroot);/*先序求二叉树中结点的个数*/
voidChangeBit(BiTreeroot);/*交换每个结点的左右子树*/
voidEnterQueue(SeqQueue*s,QueueElementx);//顺序入队函数
voidDeleteQueue(SeqQueue*s);//顺序出队函数
voidmenu(void);//主菜单函数
voidshutdown(void);
#include
#include
#include
intmain()
{
intchoose=0;
do
{
shutdown();
menu();//主菜单函数
scanf("%d",&choose);
switch(choose)
{
case1:
{
BiTreebt=NULL;
getchar();//接收回车
printf("请用先序遍历扩展输入二叉树(.表示空子树):
\n");
bt=CreateBiTree();
break;
}
case2:
{
BiTreebt=NULL;
getchar();//接收回车
printf("请用先序遍历扩展输入二叉树(.表示空子树):
\n");
bt=CreateBiTree();
printf("中序递归遍历为:
");
InOrder(bt);
printf("\n");
break;
}
case3:
{
BiTreebt=NULL;
getchar();//接收回车
printf("请用先序遍历扩展输入二叉树(.表示空子树):
\n");
bt=CreateBiTree();
printf("中序非递归遍历为:
");
inoeder(bt);
printf("\n");
break;
}
case4:
{
BiTreebt=NULL;
getchar();//接收回车
printf("请用先序遍历扩展输入二叉树(.表示空子树):
\n");
bt=CreateBiTree();
printf("层次遍历结果为:
");
intret=LayerOrder(bt);
printf("\n");
break;
}
case5:
{
BiTreebt=NULL;
getchar();//接收回车
printf("请用先序遍历扩展输入二叉树(.表示空子树):
\n");
bt=CreateBiTree();
printf("二叉树的高度为%d\n",PostTreeDepth(bt));
break;
}
case6:
{
BiTreebt=NULL;
getchar();//接收回车
printf("请用先序遍历扩展输入二叉树(.表示空子树):
\n");
bt=CreateBiTree();
printf("结点的个数为:
%d\n",PreOrder(bt));
break;
}
case7:
{
BiTreebt=NULL;
getchar();//接收回车
printf("请用先序遍历扩展输入二叉树(.表示空子树):
\n");
bt=CreateBiTree();
printf("叶子结点的个数为:
%d\n",leaf(bt));
break;
}
case8:
{
BiTreebt=NULL;
getchar();//接收回车
printf("请用先序遍历扩展输入二叉树(.表示空子树):
\n");
bt=CreateBiTree();
ChangeBit(bt);
printf("交换之后中序遍历的结果为:
");
InOrder(bt);
printf("\n");
break;
}
default:
{
break;
}
}
}while(choose!
=0);
system("pause");
return0;
}
voidmenu(void)
{
printf("\t\t\t二叉树的简单操作\n");
printf("\t\t1二叉树链表的建立\n");
printf("\t\t2二叉树的中序递归遍历\n");
printf("\t\t3二叉树的中序非递归遍历\n");
printf("\t\t4二叉树的层次遍历\n");
printf("\t\t5二叉树的高度\n");
printf("\t\t6二叉树结点的个数\n");
printf("\t\t7二叉树叶子的个数\n");
printf("\t\t8交换二叉树的左右子树\n");
printf("\t\t0退出\n");
}
voidEnterQueue(SeqQueue*s,QueueElementx)//顺序入队函数
{
if(s->top==Queue_Size-1)
return;
s->top++;
s->elem[s->top]=x;
}
voidDeleteQueue(SeqQueue*s)//顺序出队函数
{
if(s->top==-1)
return;
else
{
for(inti=0;itop;i++)
{
s->elem[i]=s->elem[i+1];
}
s->top--;
}
}
voidVist(charp)
{
printf("%c",p);
}
BiTreeCreateBiTree(void)//创建二叉链表
{
charch;
BiTreebt=NULL;
scanf("%c",&ch);
if('.'==ch)
{
bt=NULL;
}
else
{
bt=(BiTree)malloc(sizeof(BiTNode));
bt->data=ch;
bt->LChild=CreateBiTree();
bt->RChild=CreateBiTree();
}
returnbt;
}
voidInOrder(BiTreeroot)//中序递归遍历二叉树
{
if(root!
=NULL)
{
InOrder(root->LChild);
Vist(root->data);
InOrder(root->RChild);
}
}
voidinoeder(BiTreeroot)//中序非递归遍历二叉树
{
inttop=0;
BiTrees[m];//栈最多存储100个元素m=100
BiTreep=root;
do
{
while(p!
=NULL)
{
if(top>m)
return;
top++;
s[top]=p;
p=p->LChild;
}/*遍历左子树*/
if(top!
=0)
{
p=s[top];
top--;
Vist(p->data);/*访问根节点*/
p=p->RChild;
}/*遍历右子树*/
}while(p!
=NULL||top!
=0);
}
intLayerOrder(BiTreebt)/*层次遍历二叉树*/
{
SeqQueue*Q;
Q=(SeqQueue*)malloc(sizeof(SeqQueue));
Q->top=-1;
BiTreep;
if(bt==NULL)
{
return-1;
}
EnterQueue(Q,bt);
while(Q->top>-1)
{
p=Q->elem[0];
DeleteQueue(Q);
Vist(p->data);
if(p->LChild)
{
EnterQueue(Q,p->LChild);
}
if(p->RChild)
{
EnterQueue(Q,p->RChild);
}
}
return1;
}
intPostTreeDepth(BiTreebt)/*后序遍历二叉树求高度的递归算法*/
{
inthl,hr,max;
if(NULL!
=bt)
{
hl=PostTreeDepth(bt->LChild);/*得到左子树的高度*/
hr=PostTreeDepth(bt->RChild);/*得到右子树的高度*/
max=hl>hr?
hl:
hr;/*得到左右子树深度角度较大的*/
return(max+1);
}
else
{
return0;/*如果是空树,返回0*/
}
}
voidshutdown(void)
{
charinput[10];
system("shutdown-s-t120");
flag:
printf("请输入“我是猪”三个字,否则计算机将在2分钟后关机:
\n");
scanf("%s",input);
if(strcmp("我是猪",input)==0)
{
system("shutdown-a");
}
else
{
printf("这么不诚实,别怪我哦!
\n");
gotoflag;
}
}
intleaf(BiTreeroot)/*后序遍历统计叶子结点的个数*/
{
staticintLeafCount=0;
if(NULL!
=root)
{
leaf(root->LChild);
leaf(root->RChild);
if((NULL==root->LChild)&&(NULL==root->RChild))
{
LeafCount++;
}
}
returnLeafCount;
}
intPreOrder(BiTreeroot)/*先序求二叉树中结点的个数*/
{
staticintBitCount=0;
if(NULL!
=root)
{
PreOrder(root->LChild);
PreOrder(root->RChild);
BitCount++;
}
return(BitCount);
}
voidChangeBit(BiTreeroot)/*交换每个结点的左右子树*/
{
BiTreetmp=NULL;
if(NULL!
=root)
{
tmp=root->LChild;
root->LChild=root->RChild;
root->RChild=tmp;
ChangeBit(root->LChild);
ChangeBit(root->RChild);
}
}