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

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

数据结构之二叉树

实验报告

题目:二叉树的遍历和子树交换

指导老师:杨政宇

班级:通信1202

姓名:徐江

学号:0909121127

需求分析

1.演示程序分别用多种遍历算法遍历二叉树并把数据输出。

2.输入字符序列,递归方式建立二叉树。

3.在演示过程序中,用户敲击键盘,输入数据,即可看到数据的输出。

4.实现链式存储的二叉树的多种遍历算法。

遍历算法包括:

a)中序递归遍历算法、前序递归遍历算法【选】

b)中序遍历非递归算法

c)先序或后序遍历非递归算法

d)建立中序线索,并进行中序遍历和反中序遍历

5.实现二叉树的按层遍历算法

6.设计一个测试用的二叉树并创建对应的内存二叉树,能够测试自己算法的边界(包括树节点数为0、1以及>1 的不同情形)。

7.测试数据:输入数据:-+a *b -c d -e f

概要设计

说明:本程序在递归调用中用到了链表,在非递归调用时用到了栈。

1.栈的抽象数据类型

ADT Stack{

数据对象:D={a i|a i∈char,i=1,2,3……..}

数据关系:R={< a i-1,a i >| a i-1,a i∈D,i=2,3…..}

基本操作:

InitStack(&S)

操作结果:构造一个空栈

StackEmpty( S )

初始条件:栈S已存在。

操作结果:若S为空栈,则返回OK,否则返回ERROR。

Push( &S, e )

初始条件:栈S已存在。

操作结果:插入元素e为新的栈顶元素。

Pop( &S, &e )

初始条件:栈S已存在且非空。

操作结果:删除S的栈顶元素,并用e返回其值。

GetTop( S, &e )

初始条件:栈S已存在且非空。

操作结果:用e返回S的栈顶元素。

}

2.二叉树的抽象数据类型

ADT BinaryTree{

数据对象D:D是具有相同特性的数据元素的集合。

数据关系R:

若D=Φ,则R=Φ,称BinaryTree为空二叉树;

若D≠Φ,则R={H},H是如下二元关系;

(1)在D中存在惟一的称为根的数据元素root,它在关系H下无前驱;

(2)若D-{root}≠Φ,则存在D-{root}={D1,Dr},且D1∩Dr =Φ;

(3)若D1≠Φ,则D1中存在惟一的元素x1,∈H,且存在D1上的关系H1 ?H;若Dr≠Φ,则Dr中存在惟一的元素xr,∈H,且存在上的关系Hr ?H;H={,,H1,Hr};

(4)(D1,{H1})是一棵符合本定义的二叉树,称为根的左子树;(Dr,{Hr})是一棵符合本定义的二叉树,称为根的右子树。

基本操作:

CreateBiTree( &T)

初始条件:给出二叉树T的定义。

操作结果:按要求构造二叉树T。

PreOrderTraverse_re( T, print() )

初始条件:二叉树T存在,print是二叉树全部结点输出的应用函数。

操作结果:先序递归遍历T,对每个结点调用函数print一次且仅一次。一旦print()失败,则操作失败。

InOrderTraverse( T, print() )

初始条件:二叉树T存在,print是二叉树全部结点输出的应用函数。

操作结果:中序非递归遍历T,对每个结点调用函数print一次且仅一次。一旦printf()失败,则操作失败。

InOrderTraverse_re(T,print() )

初始条件:二叉树T在在,print是二叉树全部结点输出的应用函数。

操作结果:中序递归遍历T,对每个结点调用函数print一次且仅一次。一旦printf()失败,则操作失败。

PreOrderTraverse(T,print())

初始条件:二叉树T存在,print是二叉树全部结点输出的应用函数。

操作结果:先序非递归遍历T,对每个结点调用函数print一次且仅一次。一旦print()失败,则操作失败。

Levelorder(T)

初始条件:二叉树T在在。

操作结果:分层遍历二叉树T,并输出。

InOrderThreading(Thrt,T);

初始条件:二叉树T在在。

操作结果:中序遍历二叉树,并将其中序线索化。

InOrderTraverse_Thr( T, print);

初始条件:二叉树T在在。

操作结果:中序非递归遍历二叉线索树T

InThreading(p);

初始条件:结点p在在。

操作结果:结点p及子树线索化。

3.主程序的流程:

void main()

{

初始化;

提示;

执行二叉数ADT函数;

}

4.本程序包含三个模块

1)主程序模块

void main(){

初始化;

{

接受命令;

显示结果;

2)链表模块。递归调用时实现链表抽象数据类型。

3)栈模块。非递归调用时实现栈的抽象数据类型。

详细设计

1.宏定义及全局变量

#define TElemType char

#define SElemType BiTree

#define OK 1

#define OVERFLOW 0

#define ERROR 0

#define STACK_INIT_SIZE 100

#define STACKINCREMENT 10

SqStack S;

BiThrTree pre;

BiThrTree i;

2.函数定义

int CreateBiTree(BiTree &T); //创建二叉树

void PreOrderTraverse_re(BiTree T,void (*print)(TElemType e)); //先序递归遍历二叉树

void InOrderTraverse(BiTree T,int (*print)(TElemType e)); //中序非递归遍历二叉树

void InOrderTraverse_re(BiTree T,int (*print)(TElemType e)) ; //中序递归遍历二叉树

void PreOrderTraverse(BiTree T,int (*print)(TElemType e)); //先序非递归遍历二叉树

int print(TElemType e); //打印元素

void InitStack(SqStack &S); //栈的初始化

void Pop(SqStack &S,SElemType &e);

void Push(SqStack &S,SElemType &e);

int StackEmpty(SqStack S);

int GetTop(SqStack S,SElemType &e);

void Levelorder(BiTree T) ;

void InOrderThreading(BiThrTree &Thrt,BiThrTree T);

int InOrderTraverse_Thr(BiThrTree T, int (*print)(TElemType e));

void InThreading(BiThrTree p);

3.二叉树链表

数据结构:

typedef struct BiTNode{

TElemType data;

struct BiTNode *lchild ,*rchild;

PointerTag LTag , RTag;

}BiTNode , *BiTree , BiThrNode , *BiThrTree;

基本操作:

a)构造二叉树T

int CreateBiTree(BiTree &T)

{

char ch;

scanf("%c",&ch);

if(ch==' ')

T=NULL;

else

{

if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))

return ERROR;

T->data=ch;

if (CreateBiTree(T->lchild)) T->LTag=Link;

if (CreateBiTree(T->rchild)) T->RTag=Link;

}

return OK;

}

b)先序递归遍历二叉数T,并输出全部结点值。

void PreOrderTraverse_re(BiTree T,int (*print)(TElemType e))

{

if(T)

{

if(print(T->data))

PreOrderTraverse_re(T->lchild,print);

PreOrderTraverse_re(T->rchild,print);

return ;

}

else

return ;

}

c)中序非递归遍历二叉树T,并输出全部结点值

void InOrderTraverse(BiTree T,int (*print)(TElemType e)) {

SqStack S;

S.base=NULL;S.top=NULL;

SElemType p=NULL;

InitStack(S);

Push(S,T);

while(!StackEmpty(S))

{

while(GetTop(S,p)&&p)

Push(S,p->lchild);

Pop(S,p);

if(!StackEmpty(S))

{

Pop(S,p);

print(p->data);

Push(S,p->rchild);

}

}

return;

}

d)中序递归遍历二叉树T,并输出全部结点值

void InOrderTraverse_re(BiTree T,int (*print)(TElemType e)) {

if(T)

{

InOrderTraverse_re(T->lchild,print);

print(T->data);

InOrderTraverse_re(T->rchild,print);

}

}

e)中序遍历二叉树T,并将其中序线索化,Thrt指向头结点void InOrderThreading(BiThrTree &Thrt,BiThrTree T)

{

Thrt=(BiThrTree)malloc(sizeof(BiThrNode));

Thrt->LTag=Link;//建头结点

Thrt->RTag=Thread;

Thrt->rchild=Thrt;//右指针回指

if(!T)

Thrt->lchild=Thrt;

else

{

Thrt->lchild=T;

pre=Thrt;

InThreading(T);//中序遍历进行中序线索化

pre->rchild=Thrt;

pre->RTag=Thread;//最后一个结点线索化

Thrt->rchild=pre;

}

i=Thrt;

}//InOrderThreading

f)结点p线索化

void InThreading(BiThrTree p) {

if (p) {

InThreading(p->lchild); // 左子树线索化

if (!p->lchild) // 建前驱线索

{ p->LTag = Thread; p->lchild = pre; }

if (!pre->rchild) // 建后继线索

{ pre->RTag = Thread; pre->rchild = p; }

pre = p; // 保持pre指向p的前驱

InThreading(p->rchild); // 右子树线索化}

} // InThreading

g)//中序遍历线索化二叉树

int InOrderTraverse_Thr(BiThrTree T, int (*print)(TElemType e)) {

BiThrTree p=NULL;

p=T->lchild;

while(p!=T)

{

while(p->LTag==Link)

p=p->lchild;

if(!print(p->data))

return ERROR;

while(p->RTag==Thread && p->rchild!=T)

{

p=p->rchild;

print(p->data);

}

p=p->rchild;

}

return OK;

}

4.栈

数据结构:

typedef struct{

SElemType *base;

SElemType *top;

int stacksize;

}SqStack;

基本操作:

a)创建一个空栈

void InitStack(SqStack &S)

{

S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));

S.top=S.base; //初始为空

S.stacksize=STACK_INIT_SIZE;

return;

}

b)栈顶插入元素

void Push(SqStack &S,SElemType &e)

{

if(S.top-S.base>=S.stacksize)

{

S.base=(SElemType*)realloc(S.base,(STACK_INIT_SIZE+STACKINCRE MENT)*sizeof(SElemType));

S.top=S.base+S.stacksize;

S.stacksize+=STACKINCREMENT;

}

*S.top++=e;

}

c)栈顶删除元素

void Pop(SqStack &S,SElemType &e)

{

if(S.top==S.base)

return;

e=*--S.top;

return;

}

d)判断栈是否为空栈

int StackEmpty(SqStack S)

{

if(S.top==S.base)

return OK;

else

return ERROR;

}

e)e返回S的栈顶元素

int GetTop(SqStack S,SElemType &e)

{

if(S.top==S.base)

return ERROR;

e=*(S.top-1);

return OK;

}

5.主函数

void main()

{int flag;

BiTree T;

BiThrTree Thrt;

printf("******************************************************\n");

printf("** 实验12 二叉树的遍历**\n");

printf("** 1. 实现二叉树的不同遍历算法和二叉树的中序线索化算法**\n");

printf("** a) 中序递归遍历算法;**\n");

printf("** b) 先序递归遍历算法;**\n");

printf("** c) 中序遍历的非递归算法;**\n");

printf("** d) 先序或后序遍历非递归算法之一;**\n");

printf("** e) 建立中序线利用线索进行中序遍历和反中序遍历。**\n");

printf("** 2. 实现二叉树的按层遍历算法。**\n");

printf("**********************************************************\n ");

printf("\n选择操作:\n\t1.先序与中序遍历算法\n\t2.中序线索的中序遍历和反中序遍历算法\n\t3.按层遍历算法\n请选择:");

scanf("%d",&flag);

switch(flag)

{ case 1:

printf("前序递归创建二叉树(空格表示此结点为空):\n");

getchar();

CreateBiTree(T);

printf("中序递归遍历输出:");

InOrderTraverse_re(T,print);

printf("\n前序递归遍历输出:");

PreOrderTraverse_re(T,print);

printf("\n中序非递归遍历输出:");

InOrderTraverse(T,print);

printf("\n前序非递归遍历输出:");

PreOrderTraverse(T,print);

printf("\n");

break;

case 2: printf("前序递归创建二叉树(空格表示此结点为空):\n");

getchar();

CreateBiTree(T);

printf("\n中序遍历线索化二叉树:");

InOrderThreading(Thrt , T);

InOrderTraverse_Thr(Thrt , print);

break;

case 3: printf("前序递归创建二叉树(空格表示此结点为空):\n");

getchar();

CreateBiTree(T);

printf("\n按层遍历输出:");

Levelorder(T);

printf("\n");

break;

default:return;

}}

6.函数间调用关系

main

InOrderTr averse_re

CreateBit

ree

PreOrder

Traverse

InOrderTr

averse

PreOrderT

raverse

InOrderTh

reading

InOrderTra

verse_Thr

Threading

Stack操

调试分析

1、二叉树的分层遍历,开始时想用队列来做,但考虑到比较麻烦,因而改为数组模拟队列,简单易懂,课后可自行尝试用队列来做。

2.在线索化二叉树时考虑到如果将两种存储结构分开将导致两个类型的指针不能互相传值,造成许多麻烦。比较两种存储结构发现,线索二叉树比二叉树多了两个标志域LTag,Rtag。于是把两种存储结构合并为BiThrNode,并在建立二叉树时把LTag,Rtag均置为Link。程序正常运行。

3.进入演示程序BiTree.cpp,完成编译,连接(即按下Ctrl F5)进入演示界面,或直接打开执行文件BiTree.exe,产生如下图所示的界面:

⒈用户需根据用户提示信息操作,输入二叉树(以空格表示空结点),输入完成后按回车键,屏幕上打印出对应于该二叉树的各种遍历结果。如下图:

六、测试结果

输入:-+a *b -c d -e f

屏幕输出:

中序递归遍历输出:a+b*c-d

前序递归遍历输出:+a*b-cd

中序非递归遍历输出:a+b*c-d

前序非递归遍历输出:+a*b-cd

按层遍历输出:+a*b-cd

中序遍历线索化二叉树:a+b*c-d 七、附录

BiTree.cpp

BiTree.exe

#include

#include

#define QElemType BiTNode

#define TElemType char

#define OK 1

#define OVERFLOW 0

#define ERROR 0

#define STACK_INIT_SIZE 100

#define STACKINCREMENT 10

typedef enum PointerTag{Link,Thread}; //Link==0,指针,Thread==1,线索

typedef struct BiTNode{

TElemType data;

struct BiTNode *lchild ,*rchild;

PointerTag LTag , RTag;

}BiTNode , *BiTree , BiThrNode , *BiThrTree; //二叉树

#define QElemType BiTNode

#define SElemType BiTree

typedef struct{

SElemType *base;

SElemType *top;

int stacksize;

}SqStack;

//全局变量

SqStack S;

BiThrTree pre;

BiThrTree i;

/*函数声明*/

int CreateBiTree(BiTree &T); //创建二叉树

void PreOrderTraverse_re(BiTree T,void (*print)(TElemType e)); //先序递归遍历二叉树void InOrderTraverse(BiTree T,int (*print)(TElemType e)); //中序非递归遍历二叉树void InOrderTraverse_re(BiTree T,int (*print)(TElemType e)) ; //中序递归遍历二叉树

void PreOrderTraverse(BiTree T,int (*print)(TElemType e)); //先序非递归遍历二叉树int print(TElemType e); //打印元素

void InitStack(SqStack &S); //栈的初始化

void Pop(SqStack &S,SElemType &e);

void Push(SqStack &S,SElemType &e);

int StackEmpty(SqStack S);

int GetTop(SqStack S,SElemType &e);

void Levelorder(BiTree T) ;

void InOrderThreading(BiThrTree &Thrt,BiThrTree T);

int InOrderTraverse_Thr(BiThrTree T, int (*print)(TElemType e));

void InThreading(BiThrTree p);

/*二叉树的创建递归创建*/

int CreateBiTree(BiTree &T)

{

char ch;

scanf("%c",&ch);

if(ch==' ')

T=NULL;

else

{

if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))

return ERROR;

T->data=ch;

if (CreateBiTree(T->lchild)) T->LTag=Link;

if (CreateBiTree(T->rchild)) T->RTag=Link;

}

return OK;

}

/*******************************************/

/* 先序递归遍历输出*/

/*******************************************/

void PreOrderTraverse_re(BiTree T,int (*print)(TElemType e)) {

if(T)

{

if(print(T->data))

PreOrderTraverse_re(T->lchild,print);

PreOrderTraverse_re(T->rchild,print);

return ;

}

else

return ;

}

/*******************************************/

/* 中序非递归遍历输出*/

/*******************************************/

void InOrderTraverse(BiTree T,int (*print)(TElemType e)) {

SqStack S;

S.base=NULL;S.top=NULL;

SElemType p=NULL;

InitStack(S);

Push(S,T);

while(!StackEmpty(S))

{

while(GetTop(S,p)&&p)

Push(S,p->lchild);

Pop(S,p);

if(!StackEmpty(S))

{

Pop(S,p);

print(p->data);

Push(S,p->rchild);

}

}

return;

}

/*******************************************/

/* 中序递归遍历输出*/

/*******************************************/ void InOrderTraverse_re(BiTree T,int (*print)(TElemType e)) {

if(T)

{

InOrderTraverse_re(T->lchild,print);

print(T->data);

InOrderTraverse_re(T->rchild,print);

}

return ;

}

/*******************************************/

/* 按照前序非递归遍历二叉树:栈*/

/*******************************************/ void PreOrderTraverse(BiTree T,int (*print)(TElemType e)) {

SqStack S;

S.base=NULL;S.top=NULL;

SElemType p=T;//p指向当前访问的结点

InitStack(S);

while(p||!StackEmpty(S))

{

if(p)

{

print(p->data);

Push(S,p);

p=p->lchild;

}

else

{

Pop(S,p);

p=p->rchild;

}

}

return;

}

void InOrderThreading(BiThrTree &Thrt,BiThrTree T)

//中序遍历二叉树T,并将其中序线索化,Thrt指向头结点{

Thrt=(BiThrTree)malloc(sizeof(BiThrNode));

Thrt->LTag=Link;//建头结点

Thrt->RTag=Thread;

Thrt->rchild=Thrt;//右指针回指

if(!T)

Thrt->lchild=Thrt;

else

{

Thrt->lchild=T;

pre=Thrt;

InThreading(T);//中序遍历进行中序线索化

pre->rchild=Thrt;

pre->RTag=Thread;//最后一个结点线索化

Thrt->rchild=pre;

}

i=Thrt;

}//InOrderThreading

void InThreading(BiThrTree p) {

if (p) {

InThreading(p->lchild); // 左子树线索化

if (!p->lchild) // 建前驱线索

{ p->LTag = Thread; p->lchild = pre; }

if (!pre->rchild) // 建后继线索

{ pre->RTag = Thread; pre->rchild = p; }

pre = p; // 保持pre指向p的前驱InThreading(p->rchild); // 右子树线索化

}

} // InThreading

int InOrderTraverse_Thr(BiThrTree T, int (*print)(TElemType e))

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

{

BiThrTree p=NULL;

p=T->lchild;

while(p!=T)

{

while(p->LTag==Link)

p=p->lchild;

if(!print(p->data))

return ERROR;

while(p->RTag==Thread && p->rchild!=T)

{

p=p->rchild;

print(p->data);

}

p=p->rchild;

}

return OK;

}

/***************************以下为辅助函数***************************************/

int print(TElemType e)

{

printf("%c",e);

return OK;

}

/*栈函数*/

/*栈的初始化*/

void InitStack(SqStack &S)

{

S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));

S.top=S.base; //初始为空

S.stacksize=STACK_INIT_SIZE;

return;

}

/*栈顶插入元素*/

void Push(SqStack &S,SElemType &e)

{

if(S.top-S.base>=S.stacksize)

{

S.base=(SElemType*)realloc(S.base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(S ElemType));

S.top=S.base+S.stacksize;

S.stacksize+=STACKINCREMENT;

}

*S.top++=e;

}

/*栈顶删除元素*/

void Pop(SqStack &S,SElemType &e)

{

if(S.top==S.base)

return;

e=*--S.top;

return;

}

int StackEmpty(SqStack S) /*若栈为空栈,则返回OK,否则返回ERROR*/ {

if(S.top==S.base)

return OK;

else

return ERROR;

}

int GetTop(SqStack S,SElemType &e)

{

if(S.top==S.base)

return ERROR;

e=*(S.top-1);

return OK;

}

/************************************************************/

/* 按层次顺序建立一棵二叉树*/

/************************************************************/

void Levelorder(BiTree T)

{

int i,j;

BiTNode *q[20],*p; /*q[20]用于模拟队列,存储入队的结点*/

p=T;

if(p!=NULL)

{

i=1;q[i]=p;j=2;

} /*i为队首位置,j为队尾位置*/

while(i!=j)

{

p=q[i];

printf("%c",p->data); /*访问队首元素*/

if (p->lchild!=NULL)

{

q[j]=p->lchild;

j++;

}

/*若队首元素左链域不为空,则将其入队列*/

if (p->rchild!=NULL)

{

q[j]=p->rchild;

j++;

}

/*若队首元素右链域不为空,则将其入队列*/

i++; /*将队首移到下一个位置*/

}

}

void main()

{

int flag;

BiTree T;

BiThrTree Thrt;

printf("**********************************************************\n");

printf("** 实验12 二叉树的遍历**\n");

printf("** 1. 实现二叉树的不同遍历算法和二叉树的中序线索化算法**\n");

printf("** a) 中序递归遍历算法;**\n");

printf("** b) 先序递归遍历算法;**\n");

printf("** c) 中序遍历的非递归算法;**\n");

printf("** d) 先序或后序遍历非递归算法之一;**\n");

printf("** e) 建立中序线利用线索进行中序遍历和反中序遍历。**\n");

printf("** 2. 实现二叉树的按层遍历算法。**\n");

printf("**********************************************************\n");

/* printf("\n选择操作:\n\t1.先序与中序遍历算法\n\t2.中序线索的中序遍历和反中序遍历算法\n\t3.按层遍历算法\n请选择:");

scanf("%d",&flag);

switch(flag)

{

case 1:

printf("前序递归创建二叉树(空格表示此结点为空):\n");

getchar();

CreateBiTree(T);

printf("中序递归遍历输出:");

InOrderTraverse_re(T,print);

printf("\n前序递归遍历输出:");

PreOrderTraverse_re(T,print);

printf("\n中序非递归遍历输出:");

InOrderTraverse(T,print);

printf("\n前序非递归遍历输出:");

PreOrderTraverse(T,print);

printf("\n");

break;

case 2: printf("前序递归创建二叉树(空格表示此结点为空):\n");

getchar();

CreateBiTree(T);

printf("\n中序遍历线索化二叉树:");

InOrderThreading(Thrt , T);

InOrderTraverse_Thr(Thrt , print);

break;

case 3: printf("前序递归创建二叉树(空格表示此结点为空):\n");

getchar();

CreateBiTree(T);

printf("\n按层遍历输出:");

Levelorder(T);

printf("\n");

break;

default:return;

}*/

printf("前序递归创建二叉树(空格表示此结点为空):\n");

getchar();

CreateBiTree(T);

printf("中序递归遍历输出:");

InOrderTraverse_re(T,print);

printf("\n前序递归遍历输出:");

PreOrderTraverse_re(T,print);

printf("\n中序非递归遍历输出:");

InOrderTraverse(T,print);

printf("\n前序非递归遍历输出:");

PreOrderTraverse(T,print);

printf("\n按层遍历输出:");

Levelorder(T);

printf("\n中序遍历线索化二叉树:");

数据结构二叉树实验报告

实验三二叉树的遍历 一、实验目的 1、熟悉二叉树的结点类型和二叉树的基本操作。 2、掌握二叉树的前序、中序和后序遍历的算法。 3、加深对二叉树的理解,逐步培养解决实际问题的编程能力。 二、实验环境 运行C或VC++的微机。 三、实验内容 1、依次输入元素值,以链表方式建立二叉树,并输出结点的值。 2、分别以前序、中序和后序遍历二叉树的方式输出结点内容。 四、设计思路 1. 对于这道题,我的设计思路是先做好各个分部函数,然后在主函数中进行顺序排列,以此完成实验要求 2.二叉树采用动态数组 3.二叉树运用9个函数,主要有主函数、构建空二叉树函数、建立二叉树函数、访问节点函数、销毁二叉树函数、先序函数、中序函数、后序函数、范例函数,关键在于访问节点 五、程序代码 #include #include #include #define OK 1 #define ERROR 0 typedef struct TNode//结构体定义 {

int data; //数据域 struct TNode *lchild,*rchild; // 指针域包括左右孩子指针 }TNode,*Tree; void CreateT(Tree *T)//创建二叉树按,依次输入二叉树中结点的值 { int a; scanf("%d",&a); if(a==00) // 结点的值为空 *T=NULL; else // 结点的值不为空 { *T=(Tree)malloc(sizeof(TNode)); if(!T) { printf("分配空间失败!!TAT"); exit(ERROR); } (*T)->data=a; CreateT(&((*T)->lchild)); // 递归调用函数,构造左子树 CreateT(&((*T)->rchild)); // 递归调用函数,构造右子树 } } void InitT(Tree *T)//构建空二叉树 { T=NULL; } void DestroyT(Tree *T)//销毁二叉树 { if(*T) // 二叉树非空 { DestroyT(&((*T)->lchild)); // 递归调用函数,销毁左子树 DestroyT(&((*T)->rchild)); // 递归调用函数,销毁右子树 free(T); T=NULL; } } void visit(int e)//访问结点 { printf("%d ",e); }

实验三 二叉树的基本操作实现及其应用

二叉树的基本操作实现及其应用 一、实验目的 1.熟悉二叉树结点的结构和对二叉树的基本操作。 2.掌握对二叉树每一种操作的具体实现。 3.学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。 4.会用二叉树解决简单的实际问题。 二、实验内容 设计程序实现二叉树结点的类型定义和对二叉树的基本操作。该程序包括二叉树结构类型以及每一种操作的具体的函数定义和主函数。 1 按先序次序建立一个二叉树, 2按(A:先序 B:中序 C:后序)遍历输出二叉树的所有结点 以上比做,以下选做 3求二叉树中所有结点数 4求二叉树的深度 三、实验步骤 ㈠、数据结构与核心算法的设计描述 /* 定义DataType为char类型 */ typedef char DataType; /* 二叉树的结点类型 */ typedef struct BitNode { DataType data; struct BitNode *lchild,*rchild; }*BitTree; 相关函数声明: 1、/* 初始化二叉树,即把树根指针置空 */ void BinTreeInit(BitTree *BT) { BT=(BitTree)malloc(sizeof(BitNode)); BT->data=NULL; cout<<"二叉树初始化成功!"<>ch; if(ch=='#') BT=NULL; else { if(!(BT=(BitTree)malloc(sizeof(BitNode)))) exit(0);

树和二叉树实验报告

树和二叉树 一、实验目的 1.掌握二叉树的结构特征,以及各种存储结构的特点及适用范围。 2.掌握用指针类型描述、访问和处理二叉树的运算。 二、实验要求 1.认真阅读和掌握本实验的程序。 2.上机运行本程序。 3.保存和打印出程序的运行结果,并结合程序进行分析。 4.按照二叉树的操作需要,重新改写主程序并运行,打印出文件清单和运 行结果。 三、实验内容 1.输入字符序列,建立二叉链表。 2.按先序、中序和后序遍历二叉树(递归算法)。 3.按某种形式输出整棵二叉树。 4.求二叉树的高度。 5.求二叉树的叶节点个数。 6.交换二叉树的左右子树。 7.借助队列实现二叉树的层次遍历。 8.在主函数中设计一个简单的菜单,分别调试上述算法。 为了实现对二叉树的有关操作,首先要在计算机中建立所需的二叉树。建立二叉树有各种不同的方法。一种方法是利用二叉树的性质5来建立二叉树,输入数据时要将节点的序号(按满二叉树编号)和数据同时给出:(序号,数据元素0)。另一种方法是主教材中介绍的方法,这是一个递归方法,与先序遍历有点相似。数据的组织是先序的顺序,但是另有特点,当某结点的某孩子为空时以字符“#”来充当,也要输入。若当前数据不为“#”,则申请一个结点存入当前数据。递归调用建立函数,建立当前结点的左右子树。 四、解题思路 1、先序遍历:○1访问根结点,○2先序遍历左子树,○3先序遍历右子树 2、中序遍历:○1中序遍历左子树,○2访问根结点,○3中序遍历右子树 3、后序遍历:○1后序遍历左子树,○2后序遍历右子树,○3访问根结点 4、层次遍历算法:采用一个队列q,先将二叉树根结点入队列,然后退队列,输出该结点;若它有左子树,便将左子树根结点入队列;若它有右子树,便将右子树根结点入队列,直到队列空为止。因为队列的特点是先进后出,所以能够达到按层次遍历二叉树的目的。 五、程序清单 #include #include #define M 100

二叉树的基本操作实验

实验三二叉树的基本运算 一、实验目的 1、使学生熟练掌握二叉树的逻辑结构和存储结构。 2、熟练掌握二叉树的各种遍历算法。 二、实验内容 [问题描述] 建立一棵二叉树,试编程实现二叉树的如下基本操作: 1. 按先序序列构造一棵二叉链表表示的二叉树T; 2. 对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出结点的遍历序列; 3. 求二叉树的深度/结点数目/叶结点数目;(选做) 4. 将二叉树每个结点的左右子树交换位置。(选做) [基本要求] 从键盘接受输入(先序),以二叉链表作为存储结构,建立二叉树(以先序来建立), [测试数据] 如输入:ABCффDEфGффFффф(其中ф表示空格字符) 则输出结果为 先序:ABCDEGF 中序:CBEGDFA 后序:CGEFDBA 层序:ABCDEFG [选作内容] 采用非递归算法实现二叉树遍历。 三、实验前的准备工作 1、掌握树的逻辑结构。 2、掌握二叉树的逻辑结构和存储结构。 3、掌握二叉树的各种遍历算法的实现。 一实验分析 本次试验是关于二叉树的常见操作,主要是二叉树的建立和遍历。二叉树的遍历有多种方法,本次试验我采用递归法,递归法比较简单。 二概要设计 功能实现

1.int CreatBiTree(BiTree &T) 用递归的方法先序建立二叉树, 并用链表储存该二叉树 2.int PreTravel(BiTree &T) 前序遍历 3. int MidTravel(BiTree &T) 中序遍历 4.int PostTravel(BiTree &T) 后序遍历 5.int Depth(BiTree &T) //计算树的深度 6.int howmuch(BiTree T,int h) 采用树节点指针数组,用于存放遍历到的元素地址,如果有左孩子,存入地址,j加一,否则没操作,通过访问数组输出层次遍历的结果。k计算叶子数,j为总节点。 7. int exchang(BiTree &T) 交换左右子树,利用递归,当有左右孩子时才交换 三详细设计 #include #include typedef struct BiTNode { char data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree;

二叉树实验报告

实验题目:实验九——二叉树实验 算法设计(3) 问题分析: 1、题目要求:编写算法交换二叉树中所有结点的左右子树 2、设计思路:首先定义一个二叉树的数据类型,使用先序遍历建立该二叉树,遍历二叉树,设计左右子树交换的函数,再次遍历交换之后的二叉树,与先前二叉树进行比较。遍历算法与交换算法使用递归设计更加简洁。 3、测试数据: A、输入:1 2 4 0 0 5 0 0 3 0 0 交换前中序遍历:4 2 5 1 3 交换后中序遍历:3 1 5 2 4 交换前:交换后: B、输入:3 7 11 0 0 18 17 0 0 19 0 0 6 13 0 0 16 0 0 交换前中序遍历:11 7 17 18 19 3 13 6 16 交换后中序遍历:16 6 13 3 19 18 17 7 11 概要设计: 1、为了实现上述功能:①构造一个空的二叉树;②应用先序遍历输入,建立二叉树;③中序遍历二叉树;④调用左右子树交换函数;⑤中序遍历交换过后的二叉树。 2、本程序包括4个函数: ①主函数main() ②先序遍历二叉树建立函数creat_bt() ③中序遍历二叉树函数inorder() ④左右子树交换函数 exchange()

各函数间关系如下: 详细设计: 1、结点类型 typedef struct binode //定义二叉树 { int data; //数据域 struct binode *lchild,*rchild; //左孩子、右孩子 }binode,*bitree; 2、各函数操作 ① 先序遍历建二叉树函数 bitree creat_bt() { 输入结点数据; 判断是否为0{ 若是,为空; 不是,递归;} 返回二叉树; } ② 左右子树交换函数 void exchange(bitree t) { 判断结点是否为空{ 否,交换左右子树; 递归;} } ③ 中序遍历函数 void inorder(bitree bt) { 判断是否为空{ 递归左子树; 输出; 递归右子树;} } main () creat_bt () inorder () exchange ()

二叉树的建立和遍历的实验报告doc

二叉树的建立和遍历的实验报告 篇一:二叉树的建立及遍历实验报告 实验三:二叉树的建立及遍历 【实验目的】 (1)掌握利用先序序列建立二叉树的二叉链表的过程。 (2)掌握二叉树的先序、中序和后序遍历算法。 【实验内容】 1. 编写程序,实现二叉树的建立,并实现先序、中序和后序遍历。 如:输入先序序列abc###de###,则建立如下图所示的二叉树。 并显示其先序序列为:abcde 中序序列为:cbaed 后序序列为:cbeda 【实验步骤】 1.打开VC++。 2.建立工程:点File->New,选Project标签,在列表中选Win32 Console Application,再在右边的框里为工程起好名字,选好路径,点OK->finish。至此工程建立完毕。 3.创建源文件或头文件:点File->New,选File标签,在列表里选C++ Source File。给文件起好名字,选好路径,点OK。至此一个源文件就被添加到了你刚创建的工程之中。

4.写好代码 5.编译->链接->调试 #include #include #define OK 1 #define OVERFLOW -2 typedef int Status; typedef char TElemType; typedef struct BiTNode { TElemType data; struct BiTNode *lchild, *rchild; }BiTNode,*BiTree; Status CreateBiTree(BiTree &T) { TElemType ch; scanf("%c",&ch); if (ch=='#') T= NULL; else { if (!(T = (BiTNode *)malloc(sizeof(BiTNode))))

二叉树实验报告及代码

重庆交通大学综合性设计性实验报告 姓名姚远学号 631106060113 班级:计信息一班 实验项目名称:二叉树 实验项目性质:设计性实验 实验所属课程:数据结构 实验室(中心): 407机房 指导教师:鲁云平 实验完成时间: 2013 年 5 月 10 日

一、实验目的 1. 建立二叉树 2. 计算结点所在的层次 3.统计结点数量和叶结点数量 4.计算二叉树的高度 5.计算结点的度 6.找结点的双亲和子女 7.二叉树的遍历 8.二叉树的输出等等 二、实验内容及要求 1.二叉树的结点结构,二叉树的存储结构由学生自由选择和设定 2.实验完成后上交打印的实验报告,报告内容与前面所给定的实验模板相同 3.将实验报告电子版和源代码在网络教学平台提交 三、实验设备及软件 VISUAL C++软件 四、设计方案 ㈠题目(老师给定或学生自定) 二叉树的应用 ㈡设计的主要思路 在计算机科学中,二叉树是每个结点最多有两个子树的有序树。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用作二叉查找树和二叉堆或是二叉排序树。二叉树的每个结点至多只有二棵子树(不存在出度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2的i -1次方个结点;深度为k的二叉树至多有2^(k) -1个结点;对任何一棵二叉树T,如果其终端结点数(即叶子结点数)为n0,出度为2的结点数为n2,则n0 =n2 + 1。 ㈢主要功能

实现二叉树的各项操作。 五、主要代码 #include #include #include typedef struct BinTreeNode //二叉树结点类定义 { char data; //数据域 BinTreeNode *leftChild, *rightChild; //左子女、右子女链域 }*BTree; BinTreeNode *p,*q,*f; int NodeNum,Leaf; int NodeDu,nodeloc=1; void CreateBinTree(BTree &T); void preOrder(BTree T); void inOrder(BTree T); void postOrder(BTree T); int TreeNodes(BTree T); int LeafNodes(BTree T); int TreeNodedu(BTree T,char ch); void NodeLoc(BTree T,char c,int nodeloc); int Height(BTree T); BTree Parent(BTree T,char c); BTree NodeRC(BTree T,char c); BTree NodeLC(BTree T,char c); void CreateBinTree(BTree &T) {

二叉树基本操作+数据结构+实验报告

郑州轻工业学院数据结构实验报告 题目 学生姓名 学号 专业班级 完成时间 2016年月日

目录 一、系统功能介绍 (2) 二、需求分析 (2) 三、概要设计 (2) 四、详细设计 (5) 五、调试分析 (8) 六、使用说明 (8) 七、测试结果 (9) 八、心得体会 (10) 九、附录(程序代码) (11)

一、系统功能介绍 该系统主要功能是实现二叉树的定义和基本操作,包括定义二叉树的结构类型以及各个操作的具体函数的定义和主函数的定义。 各操作主要包括:初始化二叉树、按先序次序建立二叉树、检查二叉树是否为空、前序、中序、后序遍历树的方式、求树的深度、求树的结点数目、清空二叉树等九个对树的操作。 二、需求分析 本系统通过函数调用实现二叉树初始化,建立二叉树,检查树空与否,用前序、中序、后序遍历二叉树,求树的深度,求树的结点数目,清空二叉树等功能。 1)输出的形式和输出值的范围:在选择操作中,都以整型(数字)选择操作,插入和输出的数值都是char类型的字符; 2)输出的形式:在每次操作后,都会提示操作是否成功或者操作的结果; 3)程序达到的功能:完成初始化、检查是否为空、请空、遍历、求树的深度、求树的结点数目等功能; 4)测试数据设计: A,按先序次序建立二叉树。依次输入a,b,c,d,e,f,g.建立二叉树。 B,分别按先序,中序和后序遍历输出二叉树中的结点元素。 C,求树的高度和结点数。 三、概要分析 为了实现上述功能,定义二叉树的抽象数据类型。 ADT BinTree{ 数据对象D:D是具有相同特性的数据元素的集合。 数据关系R: 若D=¢,称BinTree为空二叉树 若D≠¢,则R={H},H是如下的二元关系; (1)在D中存在唯一的称为根的数据元素root,它在关系H下无前驱; (2)若D-{root}≠¢,则存在D-{root}={D1,Dr},且D1∩Dr=¢; (3)若D≠¢,则中存在唯一的元素x1,∈H,,且存在D1上的关系H1H;若则中存在唯一的元素且存在上的饿关系 (4)是一棵符合本定义的二叉树,称为根的左子树,是一棵符合本定义的二叉树,称为根的右子树。 基本操作 P:

数据结构实验二叉树

实验六:二叉树及其应用 一、实验目的 树是数据结构中应用极为广泛的非线性结构,本单元的实验达到熟悉二叉树的存储结构的特性,以及如何应用树结构解决具体问题。 二、问题描述 首先,掌握二叉树的各种存储结构和熟悉对二叉树的基本操作。其次,以二叉树表示算术表达式的基础上,设计一个十进制的四则运算的计算器。 如算术表达式:a+b*(c-d)-e/f 三、实验要求 如果利用完全二叉树的性质和二叉链表结构建立一棵二叉树,分别计算统计叶子结点的个数。求二叉树的深度。十进制的四则运算的计算器可以接收用户来自键盘的输入。由输入的表达式字符串动态生成算术表达式所对应的二叉树。自动完成求值运算和输出结果。四、实验环境 PC微机 DOS操作系统或 Windows 操作系统 Turbo C 程序集成环境或 Visual C++ 程序集成环境 五、实验步骤 1、根据二叉树的各种存储结构建立二叉树; 2、设计求叶子结点个数算法和树的深度算法; 3、根据表达式建立相应的二叉树,生成表达式树的模块; 4、根据表达式树,求出表达式值,生成求值模块; 5、程序运行效果,测试数据分析算法。 六、测试数据 1、输入数据:*(+)3 正确结果: 2、输入数据:(1+2)*3+(5+6*7);

正确输出:56 七、表达式求值 由于表达式求值算法较为复杂,所以单独列出来加以分析: 1、主要思路:由于操作数是任意的实数,所以必须将原始的中缀表达式中的操作数、操作符以及括号分解出来,并以字符串的形式保存;然后再将其转换为后缀表达式的顺序,后缀表达式可以很容易地利用堆栈计算出表达式的值。 例如有如下的中缀表达式: a+b-c 转换成后缀表达式为: ab+c- 然后分别按从左到右放入栈中,如果碰到操作符就从栈中弹出两个操作数进行运算,最后再将运算结果放入栈中,依次进行直到表达式结束。如上述的后缀表达式先将a 和b 放入栈中,然后碰到操作符“+”,则从栈中弹出a 和b 进行a+b 的运算,并将其结果d(假设为d)放入栈中,然后再将c 放入栈中,最后是操作符“-”,所以再弹出d和c 进行d-c 运算,并将其结果再次放入栈中,此时表达式结束,则栈中的元素值就是该表达式最后的运算结果。当然将原始的中缀表达式转换为后缀表达式比较关键,要同时考虑操作符的优先级以及对有括号的情况下的处理,相关内容会在算法具体实现中详细讨论。 2、求值过程 一、将原始的中缀表达式中的操作数、操作符以及括号按顺序分解出来,并以字符串的 形式保存。 二、将分解的中缀表达式转换为后缀表达式的形式,即调整各项字符串的顺序,并将括 号处理掉。 三、计算后缀表达式的值。 3、中缀表达式分解 DivideExpressionToItem()函数。分解出原始中缀表达式中的操作数、操作符以及括号,保存在队列中,以本实验中的数据为例,分解完成后队列中的保存顺序如下图所示:

二叉树的遍历算法实验报告

二叉树实验报告 09信管石旭琳 20091004418 一、实验目的: 1、理解二叉树的遍历算法及应用 2、理解哈夫曼树及其应用。 3、掌握哈夫曼编码思想。 二、实验内容: 1、建立二叉树二叉链表 2、实现二叉树递归遍历算法(中序、前序、后序) 3、求二叉树高度 4、求二叉树结点个数 5、求二叉树叶子个数 6、将序号为偶数的值赋给左子树 三、主要程序: #include #include typedef int ElemType; struct BiTNode { ElemType data; struct BiTNode *lch,*rch; }BiTNode,*BiTree; struct BiTNode *creat_bt1(); struct BiTNode *creat_bt2(); void preorder (struct BiTNode *t); void inorder (struct BiTNode *t); void postorder (struct BiTNode *t); void numbt (struct BiTNode *t); int n,n0,n1,n2; void main() { int k; printf("\n\n\n"); printf("\n\n 1.建立二叉树方法1(借助一维数组建立)"); printf("\n\n 2.建立二叉树方法2(先序递归遍历建立)"); printf("\n\n 3.先序递归遍历二叉树"); printf("\n\n 4.中序递归遍历二叉树"); printf("\n\n 5.后序递归遍历二叉树"); printf("\n\n 6.计算二叉树结点个数"); printf("\n\n 7.结束程序运行");

二叉树实验报告

题目: 编程实现二叉查找树的建立、中序遍历、元素查找等功能,要求解释实现过程及演示实际例子的运行结果。 算法描述: 首先创建二叉树结点类,其主要包括:二叉树结点数据域,指向左、右子树的指针,构造函数,设置当前结点左、右子树、数据域以及判断当前结点是否为叶子结点等。然后进行二叉树类定义,其私有部分为定义二叉树根结点指针,公有部分主要包括:构造函数、析构函数、判断二叉树是否为空树、先,中,后序遍历的递归与非递归、二叉树删除、层序遍历以及二叉树搜索等。接下来将对一些重要函数算法进行描述: 1、isLeaf函数:若该结点的左子树和右子树都为空,则为叶子结点。 2、isEmpty函数:根结点为空则为空树。 3、Parent函数:首先判断给定结点是否有双亲,根结点和空结点一定无双亲,初始化一个临时变量,用于跟进查找双亲结点,查找到后其保存的便是双亲结点。先递归在左子树中查找,如果找到,便结束递归且返回双亲结点指针;如果没有找到,再递归在右子树中查找。如果都没有找到,说明给定结点的双亲结点不在该二叉树中。 4、LeftSibling(RightSibling)函数:首先找到当前结点的双亲,然后判断双亲结点左右子树是否为空,其中必然有一个不为空,返回另一个子树指针即可。 5、DeleteBinaryTree函数:首先判断是否为空树,若为空,则返回,然后递归删除左子树,递归删除右子树,最后删除根结点。 6、PreOrder函数:首先判断是否为空树,若为空,则返回,然后访问根结点,递归遍历左子树,递归遍历右子树,结束。 7、PreOrderWithoutRecusion函数:使用栈来模拟递归过程,首先申请栈,用于保存结点指针序列,申请指针pointer保存当前根指针,然后判断栈是否为空,若栈为空且pointer为空,跳出函数,否则若pointer不为空,访问pointer所指结点,pointer入栈,pointer指向其左子树;若pointer为空,弹出栈顶元素赋给pointer,pointer指向其右子树,结束。 8、CreateTree函数:采用先序遍历序列构造二叉树,设‘0’为空结点,输入非‘0’数,生成新结点,递归创建左子树和右子树。 9、Search函数:采用先序遍历查找给定元素是否在二叉树中,首先判断树是否是空树,若是空树,则返回空指针。然后初始化临时指针temp,查找成功后temp即为所给元素所在

二叉树的遍历实验报告

二叉树的遍历实验报告 一、需求分析 在二叉树的应用中,常常要求在树中查找具有某种特征的结点,或者对树中全部结点逐一进行某种处理,这就是二叉树的遍历问题。 对二叉树的数据结构进行定义,建立一棵二叉树,然后进行各种实验操作。 二叉树是一个非线性结构,遍历时要先明确遍历的规则,先访问根结点还时先访问子树,然后先访问左子树还是先访问有右子树,这些要事先定好,因为采用不同的遍历规则会产生不同的结果。本次实验要实现先序、中序、后序三种遍历。 基于二叉树的递归定义,以及遍历规则,本次实验也采用的是先序遍历的规则进行建树的以及用递归的方式进行二叉树的遍历。 二、系统总框图

三、各模块设计分析 (1)建立二叉树结构 建立二叉树时,要先明确是按哪一种遍历规则输入,该二叉树是按你所输入的遍历规则来建立的。本实验用的是先序遍历的规则进行建树。 二叉树用链表存储来实现,因此要先定义一个二叉树链表存储结构。因此要先定义一个结构体。此结构体的每个结点都是由数据域data 、左指针域Lchild 、右指针域Rchild 组成,两个指针域分别指向该结点的左、右孩子,若某结点没有左孩子或者右孩子时,对应的指针域就为空。最后,还需要一个链表的头指针指向根结点。 要注意的是,第一步的时候一定要先定义一个结束标志符号,例如空格键、#等。当它遇到该标志时,就指向为空。 建立左右子树时,仍然是调用create ()函数,依此递归进行下去,

直到遇到结束标志时停止操作。 (2)输入二叉树元素 输入二叉树时,是按上面所确定的遍历规则输入的。最后,用一个返回值来表示所需要的结果。 (3)先序遍历二叉树 当二叉树为非空时,执行以下三个操作:访问根结点、先序遍历左子树、先序遍历右子树。 (4)中序遍历二叉树 当二叉树为非空时,程序执行以下三个操作:访问根结点、先序遍历左子树、先序遍历右子树。 (5)后序遍历二叉树 当二叉树为非空时,程序执行以下三个操作:访问根结点、先序遍历左子树、先序遍历右子树。 (6)主程序 需列出各个函数,然后进行函数调用。 四、各函数定义及说明 因为此二叉树是用链式存储结构存储的,所以定义一个结构体用以存储。 typedef struct BiTNode { char data; struct BiTNode *Lchild; struct BiTNode *Rchild;

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

学生实验报告 学院:软通学院 课程名称:数据结构与算法 专业班级:软件142 班 姓名:邹洁蒙 学号: 0143990

学生实验报告 (二) 一、实验综述 1、实验目的及要求 目的:1)掌握树与二叉树的基本概念; 2)掌握二叉树的顺序存储,二叉链表的先序遍历中序遍历和后序遍历算法; 3)掌握树的双亲表示法。 要求:1)编程:二叉树的顺序存储实现; 2)编程:二叉链表的先序遍历中序遍历和后序遍历实现; 3)编程:树的双亲表示法实现。 2、实验仪器、设备或软件 设备:PC 软件:VC6 二、实验过程(编程,调试,运行;请写上源码,要求要有注释) 1.编程:二叉树的顺序存储实现 代码: BiTree::BiTree()//建立存储空间 { data = new int[MAXSIZE]; count = 0; } void BiTree::AddNode(int e)//加结点 { int temp = 0; data[count] = e; count++;//从编号0开始保存 }

运行截图: 2.编程:二叉链表的先序遍历中序遍历和后序遍历实现代码: void InOrderTraverse(BiTree* Head)//中序遍历 { if (Head) { InOrderTraverse(Head->LeftChild); cout << Head->data<<" "; InOrderTraverse(Head->RightChild); } } void PreOrderTraverse(BiTree* Head)//先序遍历 { if (Head) { cout << Head->data << " "; PreOrderTraverse(Head->LeftChild); PreOrderTraverse(Head->RightChild); } } void PostOrderTraverse(BiTree* Head)//后序遍历 { if (Head) { PostOrderTraverse(Head->LeftChild); PostOrderTraverse(Head->RightChild); cout << Head->data << " "; } } 运行截图:

二叉树的建立和遍历的实验报告

竭诚为您提供优质文档/双击可除二叉树的建立和遍历的实验报告 篇一:二叉树遍历实验报告 数据结构实验报告 报告题目:二叉树的基本操作学生班级: 学生姓名:学号: 一.实验目的 1、基本要求:深刻理解二叉树性质和各种存储结构的特点及适用范围;掌握用指针类型描述、访问和处理二叉树的运算;熟练掌握二叉树的遍历算法;。 2、较高要求:在遍历算法的基础上设计二叉树更复杂操作算法;认识哈夫曼树、哈夫曼编码的作用和意义;掌握树与森林的存储与便利。二.实验学时: 课内实验学时:3学时课外实验学时:6学时三.实验题目 1.以二叉链表为存储结构,实现二叉树的创建、遍历(实验类型:验证型)1)问题描述:在主程序中设计一个简单的菜单,分别调用相应的函数功能:1…建立树2…前序

遍历树3…中序遍历树4…后序遍历树5…求二叉树的高度6…求二叉树的叶子节点7…非递归中序遍历树0…结束2)实验要求:在程序中定义下述函数,并实现要求的函数功能:createbinTree(binTree structnode*lchild,*rchild; }binTnode;元素类型: intcreatebinTree(binTree voidpreorder(binTreevoidInorder(binTree voidpostorder(binTreevoidInordern(binTreeintleaf(bi nTree intpostTreeDepth(binTree 2、编写算法实现二叉树的非递归中序遍历和求二叉树高度。1)问题描述:实现二叉树的非递归中序遍历和求二叉树高度2)实验要求:以二叉链表作为存储结构 3)实现过程: 1、实现非递归中序遍历代码: voidcbiTree::Inordern(binTreeinttop=0;p=T;do{ while(p!=nuLL){ stack[top]=p;;top=top+1;p=p->lchild;}; if(top>0){ top=top-1;p=stack[top];

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

算法与数据结构》课程实验报告

一、实验目的 1、实现二叉树的存储结构 2、熟悉二叉树基本术语的含义 3、掌握二叉树相关操作的具体实现方法 二、实验内容及要求 1. 建立二叉树 2. 计算结点所在的层次 3. 统计结点数量和叶结点数量 4. 计算二叉树的高度 5. 计算结点的度 6. 找结点的双亲和子女 7. 二叉树前序、中序、后序遍历的递归实现和非递归实现及层次遍历 8. 二叉树的复制 9. 二叉树的输出等 三、系统分析 (1)数据方面:该二叉树数据元素采用字符char 型,并且约定“ #”作为二叉树输入结束标识符。并在此基础上进行二叉树相关操作。 (2)功能方面:能够实现二叉树的一些基本操作,主要包括: 1. 采用广义表建立二叉树。 2. 计算二叉树高度、统计结点数量、叶节点数量、计算每个结点的度、结点所在层次。 3. 判断结点是否存在二叉树中。 4. 寻找结点父结点、子女结点。 5. 递归、非递归两种方式输出二叉树前序、中序、后序遍历。 6. 进行二叉树的复制。 四、系统设计 (1)设计的主要思路 二叉树是的结点是一个有限集合,该集合或者为空,或者是由一个根节点加上两棵分别称为左子树和右子树、互不相交的二叉树组成。根据实验要求,以及课上老师对于二叉树存储结构、基本应用的讲解,同时课后研究书中涉及二叉树代码完成二叉树模板类,并将所需实现各个功能代码编写完成,在建立菜单对功能进行调试。 (2)数据结构的设计 二叉树的存储结构有数组方式和链表方式。但用数组来存储二叉树有可能会消耗大量的存储空间,故在此选用链表存储,提高存储空间的利用率。根据二叉树的定义,二叉

数据结构实验三——二叉树基本操作及运算实验报告

《数据结构与数据库》 实验报告 实验题目 二叉树的基本操作及运算 一、需要分析 问题描述: 实现二叉树(包括二叉排序树)的建立,并实现先序、中序、后序和按层次遍历,计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目,以及二叉树常用运算。 问题分析: 二叉树树型结构是一类重要的非线性数据结构,对它的熟练掌握是学习数据结构的基本要求。由于二叉树的定义本身就是一种递归定义,所以二叉树的一些基本操作也可采用递归调用的方法。处理本问题,我觉得应该:

1、建立二叉树; 2、通过递归方法来遍历(先序、中序和后序)二叉树; 3、通过队列应用来实现对二叉树的层次遍历; 4、借用递归方法对二叉树进行一些基本操作,如:求叶子数、树的深度宽度等; 5、运用广义表对二叉树进行广义表形式的打印。 算法规定: 输入形式:为了方便操作,规定二叉树的元素类型都为字符型,允许各种字符类型的输入,没有元素的结点以空格输入表示,并且本实验是以先序顺序输入的。 输出形式:通过先序、中序和后序遍历的方法对树的各字符型元素进行遍历打印,再以广义表形式进行打印。对二叉树的一些运算结果以整型输出。 程序功能:实现对二叉树的先序、中序和后序遍历,层次遍历。计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目。对二叉树的某个元素进行查找,对二叉树的某个结点进行删除。 测试数据:输入一:ABC□□DE□G□□F□□□(以□表示空格),查找5,删除E 预测结果:先序遍历ABCDEGF 中序遍历CBEGDFA 后序遍历CGEFDBA 层次遍历ABCDEFG 广义表打印A(B(C,D(E(,G),F))) 叶子数3 深度5 宽度2 非空子孙数6 度为2的数目2 度为1的数目2 查找5,成功,查找的元素为E 删除E后,以广义表形式打印A(B(C,D(,F))) 输入二:ABD□□EH□□□CF□G□□□(以□表示空格),查找10,删除B 预测结果:先序遍历ABDEHCFG 中序遍历DBHEAGFC 后序遍历DHEBGFCA 层次遍历ABCDEFHG 广义表打印A(B(D,E(H)),C(F(,G))) 叶子数3 深度4 宽度3 非空子孙数7 度为2的数目2 度为1的数目3 查找10,失败。

实验10 二叉树的基本操作

浙江大学城市学院实验报告 课程名称数据结构基础 实验项目名称实验十二叉树的基本操作 学生姓名专业班级学号 实验成绩指导老师(签名)日期2014-12-18 一.实验目的和要求 1、掌握二叉树的链式存储结构。 2、掌握在二叉链表上的二叉树操作的实现原理与方法。 3、进一步掌握递归算法的设计方法。 二.实验内容 1、按照下面二叉树二叉链表的存储表示,编写头文件binary_tree.h,实现二叉链表的定义与基本操作实现函数;编写主函数文件test4_1.cpp,验证头文件中各个操作。 二叉树二叉链表存储表示如下: struct BTreeNode { ElemType data; // 结点值域 BTreeNode *lchild , *rchild ; // 定义左右孩子指针 } ; 基本操作如下: ①void InitBTree( BTreeNode *&BT ); //初始化二叉树BT ②void CreateBTree( BTreeNode *&BT, char *a ); //根据字符串a所给出的广义表表示的二叉树建立二叉链表存储结构 ③int EmptyBTree( BTreeNode *BT); //检查二叉树BT是否为空,空返回1,否则返回0 ④int DepthBTree( BTreeNode *BT); //求二叉树BT的深度并返回该值 ⑤int FindBTree( BTreeNode *BT, ElemType x); //查找二叉树BT中值为x的结点,若查找成功返回1,否则返回0 ⑥void PreOrder( BTreeNode *BT); //先序遍历二叉树BT ⑦void InOrder( BTreeNode *BT); //中序遍历二叉树BT ⑧void PostOrder( BTreeNode *BT); //后序遍历二叉树BT

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

问题一:二叉树遍历 1.问题描述 设输入该二叉树的前序序列为: ABC##DE#G##F##HI##J#K##(#代表空子树) 请编程完成下列任务: ⑴请根据此输入来建立该二叉树,并输出该二叉树的前序、中序和后序序列; ⑵按层次遍历的方法来输出该二叉树按层次遍历的序列; ⑶求该二叉树的高度。 2.设计描述 (1)二叉树是一种树形结构,遍历就是要让树中的所有节点被且仅被访问一次,即按一定规律排列成一个线性队列。二叉(子)树是一种递归定义的结构,包含三个部分:根结点(N)、左子树(L)、右子树(R)。根据这三个部分的访问次序对二叉树的遍历进行分类,总共有6种遍历方案:NLR、LNR、LRN、NRL、RNL和LNR。研究二叉树的遍历就是研究这6种具体的遍历方案,显然根据简单的对称性,左子树和右子树的遍历可互换,即NLR与NRL、LNR与RNL、LRN 与RLN,分别相类似,因而只需研究NLR、LNR和LRN三种即可,分别称为“先序遍历”、“中序遍历”和“后序遍历”。采用递归方式就可以容易的实现二叉树的遍历,算法简单且直观。 (2)此外,二叉树的层次遍历即按照二叉树的层次结构进行遍历,按照从上到下,同一层从左到右的次序访问各节点。遍历算法可以利用队列来实现,开始时将整个树的根节点入队,然后每从队列中删除一个节点并输出该节点的值时,都将它的非空的左右子树入队,当队列结束时算法结束。

(3)计算二叉树高度也是利用递归来实现:若一颗二叉树为空,则它的深度为0,否则深度等于左右子树的最大深度加一。 3.源程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include #include #include #define ElemType char struct BTreeNode { ElemType data; struct BTreeNode* left; struct BTreeNode* right; }; void CreateBTree(struct BTreeNode** T) { char ch; scanf_s("\n%c", &ch); if (ch == '#') *T = NULL;

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

数据结构 实 验 报 告

1. 实验目的和内容: 掌握二叉树基本操作的实现方法2. 程序分析 2.1存储结构 链式存储 2.程序流程

2.3关键算法分析 算法一:Create(BiNode* &R,T data[],int i,int n) 【1】算法功能:创建二叉树 【2】算法基本思想:利用顺序存储结构为输入,采用先建立根结点,再建立左右孩子的方法来递归建立二叉链表的二叉树 【3】算法空间时间复杂度分析:O(n) 【4】代码逻辑: 如果位置小于数组的长度则 {创建根结点 将数组的值赋给刚才创建的结点的数据域 创建左子树,如果当前结点位置为i,则左孩子位置为2i 创建右子树,如果当前结点位置为i,则右孩子位置为2i+1 } 否则R为空 算法二:CopyTree(BiNode*sR,BiNode* &dR) ) 【1】算法功能:复制构造函数 【2】算法基本思想:按照先创建根结点,再递归创建左右子树的方法来实现。 【3】算法空间时间复杂度分析:O(n) 【4】代码逻辑: 如果源二叉树根结点不为空 则{ 创建根结点 调用函数自身,创建左子树 调用函数自身,创建右子树 } 将该函数放在复制构造函数中调用,就可以实现复制构造函数

算法三:PreOrder(BiNode*R) 【1】算法功能:二叉树的前序遍历 【2】算法基本思想:这个代码用的是优化算法,提前让当前结点出栈。【3】算法空间时间复杂度分析:O(n) 【4】代码逻辑(伪代码) 如果当前结点为非空,则 { 访问当前结点 当前结点入栈 将当前结点的左孩子作为当前结点} 如果为空 { 则栈顶结点出栈 则将该结点的右孩子作为当前结点 } 反复执行这两个过程,直到结点为空并且栈空 算法四:InOrder(BiNode*R) 【1】算法功能:二叉树的中序遍历 【2】算法基本思想:递归 【3】算法空间时间复杂度分析:未知 【4】代码逻辑: 如果R为非空: 则调用函数自身遍历左孩子 访问该结点 再调用自身访问该结点的右孩子 算法五:LevelOrder(BiNode*R) 【1】算法功能:二叉树的层序遍历 【2】算法基本思想: 【3】算法空间时间复杂度分析:O(n) 【4】代码逻辑(伪代码): 若根结点非空,入队

实验五-二叉树基本操作的编程实现实验分析报告

实验五-二叉树基本操作的编程实现实验报告

————————————————————————————————作者:————————————————————————————————日期:

HUBEI UNIVERSITY OF AUTOMOTIVE TECHNOLOGY 数据结构 实验报告 这里一定填 写清楚自己 实验项目实验五实验类别基础篇 学生姓名朱忠栋学生学号20120231515 完成日期2014-12-16 指导教师付勇智 实验成绩评阅日期 评阅教师

实验五二叉树基本操作的编程实现 【实验目的】 内容:二叉树基本操作的编程实现 要求: 二叉树基本操作的编程实现(2学时,验证型),掌握二叉树的建立、遍历、插入、删除等基本操作的编程实现,也可以进一步编程实现查找等操作,存储结构主要采用顺序或链接结构。也鼓励学生利用基本操作进行一些应用的程序设计。 【实验性质】 验证性实验(学时数:2H) 【实验内容】 以下的选题都可以作为本次实验的推荐题目 1.建立二叉树,并以前序遍历的方式将结点内容输出。 2.将一个表示二叉树的数组结构转换成链表结构。 3.将表达式二叉树方式存入数组,以递归方式建立表达式之二叉树状结构,再分别输出前序、中序 及后序遍历结果,并计算出表达式之结果。 【注意事项】 1.开发语言:使用C。 2.可以自己增加其他功能。 【实验分析、说明过程】

页面不够,可续页。 根据自己选择的层次不同的实验内容,完善程序代码,调试通过后,分析说明该问题处理的详细算法过程。不需要写出详细的代码,只表达清楚详细的处理算法即可。可以采用流程图、形式语言或者其他数学表达方式来说明。 这次实验考查的主要是:递归建立二叉树,递归输出先序,中序和后序遍历的结果;非递归建立二叉树,再以非递归方式分别输出先序,中序和后序遍历的结果。 而对于基础篇考查的主要是:递归建立二叉树,递归输出先序,中序和后序遍历的结果,是以填空的方式进行考查的。 对于第一空:递归实现的先序遍历,其实现方法是: printf("%d",p->data); if(p->lchild!=NULL) preorder(p->lchild); if(p->rchild!=NULL) preorder(p->rchild); 对于第二空:递归实现的中序遍历,其实现方法是: if(p->lchild!=NULL) inorder(p->lchild); printf("%d",p->data); if(p->rchild!=NULL) inorder(p->rchild); 对于第三空:递归实现的后序遍历,其实现方法是: if(p->lchild!=NULL) postorder(p->lchild); if(p->rchild!=NULL) postorder(p->rchild); printf("%d",p->data); 【思考问题】 页面不够,可续页。 1.二叉树是树吗?它的定义为什么是递归的? 答:最多有两棵子树的有序树,称为二叉树。二叉树是一种特殊的树。具有n个结点的完全二叉树的深度为log2n +1 !!!二叉树的计算方法:若一棵二叉树为空,则其深度为0,否则其深度等于左子树和右子树的最大深度加1 2.三种根序遍历主要思路是什么? 答:大体思路差不多,但节点访问位置不一样,先序的话,是先访问,然后节点压栈,移到左子树,至节点空退栈,移到右子树。而中序的话,是先节点压栈,移到左子树,至节点空退栈,访问节点,然后移到右子树。另外,所谓前序、中序、后序遍历,全称是前根序遍历,中根序遍历,后根序遍历,不管哪种遍历,访问左子树一定在访问右子树之前,不同的就是根的访问时机。 所以三种递归/或非递归,程序思路都是一样的。 3.如果不用遍历算法一般启用什么数据结构实现后序遍历? 答:用栈实现后序遍历。 4.举出二叉树的应用范例? 答:一个集合的幂集、排列问题、组合问题

相关文档
最新文档