二叉树的建立及遍历.docx
- 文档编号:28229446
- 上传时间:2023-07-09
- 格式:DOCX
- 页数:17
- 大小:61.77KB
二叉树的建立及遍历.docx
《二叉树的建立及遍历.docx》由会员分享,可在线阅读,更多相关《二叉树的建立及遍历.docx(17页珍藏版)》请在冰豆网上搜索。
二叉树的建立及遍历
数据结构实验五
课程数据结构实验名称二叉树的建立及遍历第页
专业班级学号
姓名
实验日期:
年月日评分
一、实验目的
1.学会实现二叉树结点结构和对二叉树的基本操作。
2.掌握对二叉树每种操作的具体实现,学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。
二、实验要求
1.认真阅读和掌握和本实验相关的教材内容。
2.编写完整程序完成下面的实验内容并上机运行。
3.整理并上交实验报告。
三、实验内容
1.编写程序任意输入二叉树的结点个数和结点值,构造一棵二叉树,采用三种递归遍历算法(前序、中序、后序)对这棵二叉树进行遍历并计算出二叉树的高度。
2.编写程序生成下面所示的二叉树,并采用先序遍历的非递归算法对此二叉树进行遍历。
四、实验步骤
(描述实验步骤及中间的结果或现象。
在实验中做了什么事情,怎么做的,发生的现象和中间结果)
第一题
#include"stdafx.h"
#include"iostream.h"
#include"stdlib.h"
#include"stdio.h"
#include
usingnamespacestd;
#defineNULL0
#defineOK1
#defineOVERFLOW-1
typedefintStatus;
typedefstructnode
{
chardata;
structnode*lchild;
structnode*rchild;
}*bitree;
intk=0;
intdepth(bitreeT)//树的高度
{
if(!
T)return0;
else
{
intm=depth(T->lchild);
intn=depth(T->rchild);
return(m>n?
m:
n)+1;
}
}
//先序,中序建树
structnode*create(char*pre,char*ord,intn)
{
structnode*T;
intm;
T=NULL;
if(n<=0)
{
returnNULL;
}
else
{
m=0;
T=new(structnode);
T->data=*pre;
T->lchild=T->rchild=NULL;
while(ord[m]!
=*pre)
m++;
T->lchild=create(pre+1,ord,m);
T->rchild=create(pre+m+1,ord+m+1,n-m-1);
returnT;
}
}
//中序递归遍历
voidinorder(structnode*T)
{
if(!
T)
return;
else
{
inorder(T->lchild);
cout<
inorder(T->rchild);
}
}
voidinpre(structnode*T)
{
if(!
T)
return;
else
{
cout<
inpre(T->lchild);
inpre(T->rchild);
}
}
voidpostorder(structnode*T)
{
if(!
T)
return;
else
{
postorder(T->lchild);
postorder(T->rchild);
cout<
}
}
//先序非递归遍历
voidinpre1(structnode*T)
{
structnode*p;
structnode*stack[20];
inttop=0;
p=T;
cout<<"非递归先序";
while(p||top!
=0)
{
while(p)
{
stack[top++]=p;
cout<
p=p->lchild;
}
p=stack[--top];
p=p->rchild;
}
}
//中序非递归遍历
voidinorder1(structnode*T)
{
structnode*p;
structnode*stack[20];
inttop=0;
p=T;
cout<<"非递归中序";
while(p||top!
=0)
{
while(p)
{
stack[top++]=p;
p=p->lchild;
}
p=stack[--top];
cout<
p=p->rchild;
}
}
//主函数
intmain()
{
bitreeT;
charpre[30],ord[30];
intn,m;
gets(pre);
gets(ord);
n=strlen(pre);
T=create(pre,ord,n);
inpre(T);
cout< postorder(T); cout< inorder(T); cout< inpre1(T); cout< inorder1(T); cout< m=depth(T); cout<<"二叉树高度为: "< return0; } 第二题: #include"stdafx.h" #include"iostream.h" #include"stdlib.h" #include"stdio.h" #include usingnamespacestd; #defineNULL0 #defineOK1 #defineOVERFLOW-1 typedefintStatus; typedefstructnode { chardata; structnode*lchild; structnode*rchild; }*bitree; StatusCreate(bitree&T)//按先序次序输入二叉树中结点的值,! 表示空树 { chare; cout<<"输入树的元素: "< cin>>e; if(e=='! ')T=NULL; else { if(! (T=(node*)malloc(sizeof(node)))) exit(OVERFLOW); T->data=e; Create(T->lchild); Create(T->rchild); } returnOK; } //先序非递归遍历 voidinpre(structnode*T) { structnode*p; structnode*stack[20]; inttop=0; p=T; cout<<"非递归先序"; while(p||top! =0) { while(p) { stack[top++]=p; cout< p=p->lchild; } p=stack[--top]; p=p->rchild; } } //主函数 intmain() { bitreeT; Create(T); cout<<"输出的元素为: "< inpre(T); return0; } 五实验结果 第一题: 输入先序为-+a*b%cd/ef 输入后序为a+b*c%d-e/f 得出结果: 输入先序为abcd 输入后序为bacd 得出结果: 第二题: 六实验总结 1为什么头文件只用#include 。 于是就在想,反正以后不管这些头文件有没用到头写进去,省得一大堆麻烦。 2用先序建树的时候虽然只要输入一个字符串,但是要判断空树的情况。 比较麻烦。 我个人觉得用先序与中序联合建树比较简单。 因为这样只要输入先序与中序就可以建树了。 3对于三种遍历的过程,要是用递归写的就根据书上所给出的遍历步骤做稍微的调整就好了。 至于非递归的三种遍历,中序最为简单,用一个栈就可以完成了,思路是边进栈边收索左孩子,直到左孩子为空的时候才开始进行出栈输出再收索右孩子的操作。 而非递归的先序遍历基本可以和中序一样,建立一个队列,在进栈的时候队列也进同样的元素,但是不与栈一起出栈。 而是在最后进栈出栈结束的时候,对队列进行出队列操作即可。 4二叉树对于进行表达式的前缀,中缀和后缀的表示有明显的优势,既方便,又容易理解。 其先序,中序和后序分别对应这表达式的前缀,中缀和后缀。 5在建树与进行树的遍历的时候一定要理解其建树与遍历的整个过程。 不然就会连为什么这样做都不知道。 在遍历树的时候最常用到的就是栈的结构了(非递归)。 七: 思考与提高 1.如何计算二叉链表存储的二叉树中度数为1的结点数? 答: intcountleaf(bitreet,intcount) { if(! (t->lchild)&&(t->rchild) count++; elseif((t->lchild)&&! (t->rchild)) count++; countleaf(t->lchild); countleaf(t->rchild); returncount; } 2.已知有—棵以二叉链表存储的二叉树,root指向根结点,p指向二叉树中任一结点,如何求从根结点到p所指结点之间的路径? 答: voidfoundp(bitreet) { if(t==p) { Push(s,t->data); Pop(s,t->data); } foundp(t->lchild); foundp(t->rchid); } 1.先序遍历非递归算法 #definemaxsize100 typedefstruct { BitreeElem[maxsize]; inttop; }SqStack; voidPreOrderUnrec(Bitreet) { SqStacks; StackInit(s); p=t; while(p! =null||! StackEmpty(s)) { while(p! =null)//遍历左子树 { visite(p->data); push(s,p); p=p->lchild; }//endwhile if(! StackEmpty(s))//通过下一次循环中的内嵌while实现右子树遍历 { p=pop(s); p=p->rchild; }//endif }//endwhile }//PreOrderUnrec 2.中序遍历非递归算法 #definemaxsize100 typedefstruct { BitreeElem[maxsize]; inttop; }SqStack; voidInOrderUnrec(Bitreet) { SqStacks; StackInit(s); p=t; while(p! =null||! StackEmpty(s)) { while(p! =null)//遍历左子树 { push(s,p); p=p->lchild; }//endwhile if(! StackEmpty(s)) { p=pop(s); visite(p->data);//访问根结点 p=p->rchild;//通过下一次循环实现右子树遍历 }//endif }//endwhile }//InOrderUnrec 3.后序遍历非递归算法 #definemaxsize100 typedefenum{L,R}tagtype; typedefstruct { Bitreeptr; tagtypetag; }stacknode; typedefstruct { stacknodeElem[maxsize]; inttop; }SqStack; voidPostOrderUnrec(Bitreet) { SqStacks; stacknodex; StackInit(s); p=t; do { while(p! =null)//遍历左子树 { x.ptr=p; x.tag=L;//标记为左子树 push(s,x); p=p->lchild; } while(! StackEmpty(s)&&s.Elem[s.top].tag==R) { x=pop(s); p=x.ptr; visite(p->data);//tag为R,表示右子树访问完毕,故访问根结点 } if(! StackEmpty(s)) { s.Elem[s.top].tag=R;//遍历右子树 p=s.Elem[s.top].ptr->rchild; } }while(! StackEmpty(s)); }//PostOrderUnrec
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 二叉 建立 遍历