二叉树的建立及遍历

二叉树的建立及遍历
二叉树的建立及遍历

数据结构实验五

课程数据结构实验名称二叉树的建立及遍历第页

专业班级学号

姓名

实验日期:年月日评分

一、实验目的

1.学会实现二叉树结点结构和对二叉树的基本操作。

2.掌握对二叉树每种操作的具体实现,学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。

二、实验要求

1.认真阅读和掌握和本实验相关的教材内容。

2.编写完整程序完成下面的实验内容并上机运行。

3.整理并上交实验报告。

三、实验内容

1.编写程序任意输入二叉树的结点个数和结点值,构造一棵二叉树,采用三种递归遍历算法(前序、中序、后序)对这棵二叉树进行遍历并计算出二叉树的高度。

2 .编写程序生成下面所示的二叉树,并采用先序遍历的非递归算法对此二叉

树进行遍历。

四、实验步骤

(描述实验步骤及中间的结果或现象。在实验中做了什么事情,怎么做的,发生的现象和中间结果)

第一题

#include "stdafx.h"

#include"iostream.h"

#include"stdlib.h"

#include"stdio.h"

#include

using namespace std;

#defineNULL0

#define OK 1

#defineOVERFLOW -1

typedefint Status;

typedef struct node

{

chardata;

?struct node *lchild;

struct node*rchild;

}*bitree;

int k=0;

int depth(bitree T)//树的高度

?if(!T)return0;

else

?{

?intm=depth(T->lchild);

int n=depth(T->rchild);

?return (m>n?m:n)+1;

}

//先序,中序建树

structnode*create(char *pre,char *ord,int n)

{

?struct node*T;

intm;

T=NULL;

?if(n<=0)

?{

?returnNULL;

?else

?{

?m=0;

??T=new(struct node);

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);

return T;

}

//中序递归遍历

voidinorder(struct node *T)

{

if(!T)

?return;

?else

?{

?inorder(T->lchild);

cout<<T->data;

??inorder(T->rchild);

?}

}

void inpre(struct node *T)

{

?if(!T)

return;

else

?{

??cout<

inpre(T->lchild);

inpre(T->rchild );

??

?}

}

voidpostorder(struct node *T)

{

if(!T)

?return;

?else

?{

postorder(T->lchild);

?postorder (T->rchild); ??cout<<T->data;

?}

}

//先序非递归遍历

voidinpre1(struct node *T)

{

?structnode*p;

?structnode *stack[20];

int top=0;

p=T;

cout<<"非递归先序";

while(p||top!=0)

{

??while(p)

??{

?stack[top++]=p;

cout<

??p=p->lchild;

?}

??p=stack[--top];

?

?p=p->rchild ;

}

}

//中序非递归遍历

void inorder1(struct node *T) {

?struct node*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<data;

??p=p->rchild;

?}

}

//主函数

intmain()

{

?bitree T;

char pre[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<<endl;

inorder1(T);

cout<<endl;

m=depth(T);

cout<<"二叉树高度为:"<

?return 0;

}

第二题:

#include"stdafx.h"

#include"iostream.h"

#include"stdlib.h"

#include"stdio.h"

#include

using namespace std;

#define NULL 0

#defineOK 1

#defineOVERFLOW-1

typedef intStatus;

typedefstruct node

?char data;

?struct node *lchild;

structnode*rchild;

}*bitree;

Status Create(bitree&T) //按先序次序输入二叉树中结点的值,!表示空树{

chare;

cout<<"输入树的元素:"<<endl;

cin>>e;

if(e=='!') T=NULL;

else

?{

if(!(T=(node*)malloc(sizeof(node)))) ?exit(OVERFLOW);

?T->data=e;

Create(T->lchild);

??Create(T->rchild);

}

return OK;

}

//先序非递归遍历

voidinpre(struct node *T)

struct node*p;

?struct node *stack[20];

inttop=0;

?p=T;

cout<<"非递归先序";

while(p||top!=0)

?{

??while (p)

??{

??stack[top++]=p;

?cout<data;

???p=p->lchild;

??}

?p=stack[--top];

?

??p=p->rchild ;

?}

}

//主函数

intmain()

?bitree T;

Create(T);

cout<<"输出的元素为:"<

?inpre(T);

return 0;

五实验结果

第一题:

输入先序为-+a*b%cd/ef 输入后序为a+b*c%d-e/f 得出结果:

输入先序为abcd

输入后序为bacd

得出结果:

第二题:

六实验总结

1 为什么头文件只用#include using namespace std;不行,要把所写到的程序中所包含的头文件头写进去。。于是就在想,反正以后不管这些头文件有没用到头写进去,省得一大堆麻烦。

2 用先序建树的时候虽然只要输入一个字符串,但是要判断空树的情况。比较麻烦。我个人觉得用先序与中序联合建树比较简单。因为这样只要输入先序与中序就可以建树了。

3对于三种遍历的过程,要是用递归写的就根据书上所给出的遍历步骤做稍微的调整就好了。至于非递归的三种遍历,中序最为简单,用一个栈就可以完成了,思路是边进栈边收索左孩子,直到左孩子为空的时候才开始进行出栈输出再收索右孩子的操作。而非递归的先序遍历基本可以和中序一样,建立一个队列,在进栈的时候队列也进同样的元素,但是不与栈一起出栈。而是在最后进栈出栈结束的时候,对队列进行出队列操作即可。

4 二叉树对于进行表达式的前缀,中缀和后缀的表示有明显的优势,既方便,又容易理解。其先序,中序和后序分别对应这表达式的前缀,中缀和后缀。

5在建树与进行树的遍历的时候一定要理解其建树与遍历的整个过程。不然就会连为什么这样做都不知道。在遍历树的时候最常用到的就是栈的结构了(非递归)。

七:思考与提高

1.如何计算二叉链表存储的二叉树中度数为1的结点数?

答:int countleaf(bitree t,int count)

{

if(!(t->lchild) &&(t->rchild)

count++;

else if ((t->lchild)&&!(t->rchild))

count++;

countleaf(t->lchild);

countleaf(t->rchild);

return count;

}

2.已知有—棵以二叉链表存储的二叉树,root指向根结点,p指向二叉树中任一结点,如何求从根结点到p所指结点之间的路径?

答:void foundp(bitreet)

{

if(t==p)

Push(s,t->data);

Pop(s,t->data);

}

foundp(t->lchild);

foundp(t->rchid);

}

相关主题
相关文档
最新文档