数据结构二叉树实验报告

数据结构二叉树实验报告
数据结构二叉树实验报告

数据结构实习题目二

二叉树及其操作

尹星晨 (0806230331)

一、问题描述

利用先序建立一棵二叉树,数据以字符串形式从键盘输入。在此二叉树上完成如下操作:

必做:

(1)实现二叉树的前序、中序、后序遍历。

(2)求出二叉树叶子结点的数目。

(3)求二叉树的树高。

(4)完成二叉树的左右子树交换,输出交换后的前序、中序遍历序列。

选做:

(1)给出二叉树的非递归后序遍历。

(2)将二叉树扩充为中序线索树,写出非递归的中序遍历。

(3)已知在两个数组中分别有前序和中序遍历序列,试建立该二叉树。

二、算法描述

1、整体思路:

S1: 建立二叉树;

S2: 递归遍历该二叉树;

S3: 二叉树的相关操作;

S4: 非递归后续遍历;

S5: 中序线索化及输出;

S6: 由数组中的序列建立二叉树且输出;

2、细节描述:

1)先序创建二叉树

默认为键盘输入,当输入‘ # ’时,输入结束;当输入‘ @’时当前结点为空;当输入其他字符时,该字符保存入当前结点的数据域。

void Create_BinTree(BinTree *T)

{

char ch;cin>>ch;//从键盘接收输入字符

if(ch=='#')return;//当输入为#时,输入结束

else{//否则继续

if(ch=='@') *T=NULL;//当输入为@时,当前结点为空

else{//否则保存该结点

*T=(BinTree)malloc(sizeof(BinTreeNode));//为当前结点申请空间

(*T)->data=ch;//键盘接收的字符保存入数据域

Create_BinTree(&(*T)->lchild);//递归方法创建左孩子结点

Create_BinTree(&(*T)->rchild); //递归方法创建右孩子结点

}}}//创建结束

2)递归方法遍历二叉树

以下涉及的遍历方法均采用递归遍历,非递归的先序,中序,后序遍历将在第四小节中涉及。

void NR_PreOrder(BinTree T)void NR_InOrder(BinTree T)void NR_PostOrder(BinTree T) {// 非递归方法的先序遍历{// 非递归方法的中序遍历{// 非递归方法的后序遍历if(T){// 若 T 树非空则遍历if(T){if(T){

cout<data;//先序遍历NR_InOrder(T->lchild);NR_PostOrder(T->lchild);

NR_PreOrder(T->lchild);//递归cout<data;//中序遍历NR_PostOrder(T->rchild);

NR_PreOrder(T->rchild);//递归NR_InOrder(T->rchild);cout<data;//后序遍历

}}}}}}

3)二叉树相关操作

这里涉及的关于二叉树的相关操作的方法均采用递归法

a)计算二叉树叶子结点数目

int LeafNum(BinTree T)

{//计算二叉树 T 叶子结点数

if(T){//若树 T 非空则开始计算

int m=LeafNum(T->lchild);//递归计算以左孩子结点为根的叶子数

int n=LeafNum(T->rchild);;//递归计算以右孩子结点为根的叶子数

if(m+n==0) return 1;//只有根结点

else return m+n;//返回左右孩子的叶子总数

}else return 0;//树空返回 0

}

b)求二叉树树高

int Height(BinTree T)

{//求二叉树 T 的高度

if(T==NULL)return 0;//若树空,高度为 0

else{

int lheight=Height(T->lchild);//递归法求以左孩子为根的树的高度

int rheight=Height(T->rchild);//递归法求以右孩子为根的树的高度

return 1+(lheight>rheight ? lheight : rheight);//返回最大值为树的高度}}

c)二叉树左右子树交换

void exchange(BinTree T)

{//二叉树左右子树交换

if(T->lchild==NULL && T->rchild==NULL) return;//若一边为空则无法交换

else{

BinTreeNode * temp=NULL;//

定义临时结点辅助交换

temp=T->lchild;

T->lchild=T->rchild;

交换左右结点

T->rchild=temp;

}

if(T->lchild) exchange(T->lchild);//递归交换左孩子

if(T->rchild) exchange(T->rchild);//递归交换右孩子

}

4)非递归后序遍历

采用栈辅助实现非递归后序遍历

void PostOrder( BinTree T)

{//非递归后序遍历

stack s;

BinTreeNode *cur = T,*visited = NULL;

while( ! s.empty() || cur != NULL ){

while( cur != NULL ){

s.push( cur );

cur = cur->lchild;

}

cur = s.top();

if( cur->rchild == visited || cur->rchild == NULL ){

cout<data;

s.pop();

visited = cur;

cur = NULL;

}

else cur = cur->rchild;

}}

5)中序线索化

typedef struct BinThrNode{

char data;

struct BinThrNode * lchild, * rchild;

int ltag,rtag;

}BinThrNode,*BinThrTree;

BinThrTree pre;

void Creat_BinThrTree(BinTree * T,BinThrTree * p)

{

if(T){

*p=(BinThrTree)malloc(sizeof(BinThrNode));

(*p)->data=(*T)->data;

Creat_BinThrTree(&(*T)->lchild,p);

Creat_BinThrTree(&(*T)->rchild,p);

}}

void Inthread(BinThrTree p)

{//中序线索化二叉树

if(p){

Inthread(p->lchild);

if(p->lchild) p->ltag=0;

else p->ltag=1;

if(p->rchild) p->rtag=0;

else p->rtag=1;

if(pre){

if(pre->rtag==1)pre->rchild=p;

if(p->ltag==1)p->lchild=pre;

}

pre=p;

Inthread(p->rchild);

}}

BinThrTree insucc(BinThrTree p)

{//寻找p结点的后继

if(p->rtag==1)return p->rchild;

else{

p=p->rchild;

while(p->ltag==0){

p=p->lchild;

return p;

}}}

void T_InOrder(BinThrTree T)

{//中序遍历线索化后的二叉树

BinThrTree p=T;

if(p){

while(p->ltag==0) p=p->lchild;

do{

cout<data;

p=insucc(p);

}while(p);

}}

6)由数组中已有的前序。中序序列建立二叉树

void set(BinTreeNode *&p,char pre[],char in[],int p1,int q1,int p2,int q2)

{//p1,q1,p2,q2分别为数组前序,中序的边界

p=new BinTreeNode;

p->data=pre[p1];

// 建立根结点 , 输入数值

int t=p2;

while(in[t]!=pre[p1]) t++;// 中序数组后移

if(t==p2) p->lchild=NULL; //无左子树

else set(p->lchild,pre,in,p1+1,p1+t-p2,p2,t-1);// 递归

if(t==q2) p->rchild=NULL; //无右子树

else set(p->rchild,pre,in,p1+t-p2+1,q1,t+1,q2);// 递归}

三、程序结构

1 、数据结构;

typedef struct BinTreeNode{

ElemType data;//数据区

struct BinTreeNode *lchild,*rchild;//左右孩子结点}BinTreeNode,*BinTree;

typedef struct BinThrNode{//中序线索化时定义的结点

char data; //数据区

struct BinThrNode * lchild, * rchild; //左右孩子结点

int ltag,rtag;//标志

}BinThrNode,*BinThrTree;

2 、函数调用结构:

3、函数功能说明:

功能区函数名功能描述创建二叉树Create_BinTree()创建二叉树(采用先序建立二叉树)

Traversal()递归遍历二叉树

NR_PreOrder()递归遍历二叉树 _ 先序

遍历

NR_InOrder()递归遍历二叉树 _ 中序

NR_PostOrder()递归遍历二叉树 _ 后序

Operation()二叉树基本操作

LeafNum()计算二叉树叶子结点数目操作

Height()计算二叉树的树高

Exchang()e交换二叉树左右子树

非递归R_PostOrder()非递归遍历二叉树 _ 后序

Creat_BinThrTree()创建修改后的含有标记的二叉树

Inthread()中序线索化

中序线索化

Insucc()寻找当前结点的后继结点

T_InOrder()非递归遍历二叉树 _ 中序

由数组创建TrFrArray()由数组创建二叉树

四、测试结果与分析

测试结果

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