数据结构 二叉树遍历实验报告.docx
《数据结构 二叉树遍历实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构 二叉树遍历实验报告.docx(28页珍藏版)》请在冰豆网上搜索。
![数据结构 二叉树遍历实验报告.docx](https://file1.bdocx.com/fileroot1/2023-1/23/b85e661f-8504-458c-8f85-e9bdf2eea4fd/b85e661f-8504-458c-8f85-e9bdf2eea4fd1.gif)
数据结构二叉树遍历实验报告
数据结构之二叉树
实验 报告
题目:
二叉树得遍历与子树交换
指导老师:
杨政宇
班级:
通信1202
姓名:
徐江
学号:
0909121127
需求分析
1.演示程序分别用多种遍历算法遍历二叉树并把数据输出.
2.输入字符序列,递归方式建立二叉树.
3、在演示过程序中,用户敲击键盘,输入数据,即可瞧到数据得输出.
4、实现链式存储得二叉树得多种遍历算法。
遍历算法包括:
a)中序递归遍历算法、前序递归遍历算法【选】
b)中序遍历非递归算法
c)先序或后序遍历非递归算法
d)建立中序线索,并进行中序遍历与反中序遍历
5、实现二叉树得按层遍历算法
6、设计一个测试用得二叉树并创建对应得内存二叉树,能够测试自己算法得边界(包括树节点数为0、1以及>1 得不同情形)。
7、测试数据:
输入数据:
-+a*b—c d -ef
概要设计
说明:
本程序在递归调用中用到了链表,在非递归调用时用到了栈。
1.栈得抽象数据类型
ADT Stack{
数据对象:
D={ai|ai∈char,i=1,2,3……、、}
数据关系:
R={〈ai-1,ai>|ai-1,ai ∈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、二叉树得抽象数据类型
ADTBinaryTree{
数据对象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,〈root,x1〉∈H,且存在D1上得ﻩﻩ 关系H1⊆H;若Dr≠Φ,则Dr中存在惟一得元素xr,<root,xr〉∈H,且ﻩﻩ存在上得关系Hr ⊆H;H={,<root,xr>,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、主程序得流程:
voidmain()
{
ﻩ初始化;
提示;
执行二叉数ADT函数;
}
4、本程序包含三个模块
1)主程序模块
voidmain(){
初始化;
{
接受命令;
显示结果;
}
}
2)链表模块.递归调用时实现链表抽象数据类型.
3)栈模块。
非递归调用时实现栈得抽象数据类型。
详细设计
1、宏定义及全局变量
#defineTElemTypechar
#define SElemTypeBiTree
#defineOK1
#defineOVERFLOW0
#defineERROR0
#defineSTACK_INIT_SIZE100
#define STACKINCREMENT10
SqStackS;
BiThrTreepre;
BiThrTree i;
2、函数定义
intCreateBiTree(BiTree &T);ﻩ//创建二叉树
void PreOrderTraverse_re(BiTreeT,void(*print)(TElemTypee));//先序递归遍历二叉树
voidInOrderTraverse(BiTree T,int(*print)(TElemTypee));ﻩﻩ//中序非递归遍历二叉树
voidInOrderTraverse_re(BiTreeT,int(*print)(TElemTypee));//中序递归遍历二叉树
voidPreOrderTraverse(BiTreeT,int(*print)(TElemTypee));//先序非递归遍历二叉树
intprint(TElemTypee);ﻩ//打印元素
voidInitStack(SqStack&S);ﻩ//栈得初始化
voidPop(SqStack&S,SElemType &e);
void Push(SqStack &S,SElemType&e);
intStackEmpty(SqStackS);
intGetTop(SqStackS,SElemType&e);
voidLevelorder(BiTreeT);
voidInOrderThreading(BiThrTree&Thrt,BiThrTree T);
intInOrderTraverse_Thr(BiThrTreeT,int(*print)(TElemType e));
voidInThreading(BiThrTree p);
3、二叉树链表
数据结构:
typedef structBiTNode{
ﻩTElemTypedata;
ﻩstruct BiTNode*lchild,*rchild;
PointerTagLTag,RTag;
}BiTNode, *BiTree,BiThrNode,*BiThrTree;
基本操作:
a)构造二叉树T
intCreateBiTree(BiTree&T)
{
ﻩchar ch;
ﻩscanf("%c",&ch);
ﻩif(ch==’’)
ﻩT=NULL;
else
{
ﻩif(!
(T=(BiTNode*)malloc(sizeof(BiTNode))))
ﻩreturnERROR;
ﻩT->data=ch;
ﻩﻩif (CreateBiTree(T->lchild)) T->LTag=Link;
ﻩﻩif(CreateBiTree(T—>rchild))T—〉RTag=Link;
ﻩ}
ﻩreturnOK;
}
b)先序递归遍历二叉数T,并输出全部结点值。
voidPreOrderTraverse_re(BiTree T,int(*print)(TElemTypee))
{
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)(TElemTypee))
{
ﻩSqStackS;
S、base=NULL;S、top=NULL;
SElemTypep=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,并输出全部结点值
voidInOrderTraverse_re(BiTreeT,int (*print)(TElemType e))
{
if(T)
{
InOrderTraverse_re(T->lchild,print);
print(T-〉data);
InOrderTraverse_re(T—>rchild,print);
}
}
e)中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
voidInOrderThreading(BiThrTree&Thrt,BiThrTreeT)
{
ﻩ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线索化
voidInThreading(BiThrTreep){
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)//中序遍历线索化二叉树
intInOrderTraverse_Thr(BiThrTreeT,int (*print)(TElemTypee))
{
ﻩBiThrTreep=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、栈
数据结构:
typedefstruct{
ﻩﻩSElemType *base;
SElemType*top;
intstacksize;
}SqStack;
基本操作:
a)创建一个空栈
voidInitStack(SqStack &S)
{
S、base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
ﻩS、top=S、base;ﻩ//初始为空
ﻩS、stacksize=STACK_INIT_SIZE;
ﻩreturn;
}
b)栈顶插入元素
voidPush(SqStack &S,SElemType&e)
{
ﻩif(S、top-S、base〉=S、stacksize)
ﻩ{
ﻩﻩS、base=(SElemType*)realloc(S、base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(SElemType));
S、top=S、base+S、stacksize;
ﻩﻩS、stacksize+=STACKINCREMENT;
ﻩ}
*S、top++=e;
}
c)栈顶删除元素
voidPop(SqStack&S,SElemType&e)
{
ﻩif(S、top==S、base)
return;
ﻩe=*--S、top;
ﻩreturn;
}
d)判断栈就是否为空栈
intStackEmpty(SqStackS)ﻩﻩ
{
if(S、top==S、base)
return OK;
else
returnERROR;
}
e)e返回S得栈顶元素
int GetTop(SqStackS,SElemType&e)
{
if(S、top==S、base)
ﻩreturn ERROR;
ﻩe=*(S、top—1);
return OK;
}
5、主函数
voidmain()
{int flag;
BiTreeT;
BiThrTreeThrt;
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)
ﻩ{ case1:
ﻩ
ﻩ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;
ﻩcase2:
printf(”前序递归创建二叉树(空格表示此结点为空):
\n");
ﻩﻩﻩﻩgetchar();
ﻩCreateBiTree(T);
ﻩﻩprintf("\n中序遍历线索化二叉树:
”);
ﻩﻩInOrderThreading(Thrt,T);
ﻩﻩﻩInOrderTraverse_Thr(Thrt ,print);
ﻩﻩﻩbreak;
ﻩﻩcase3:
printf(”前序递归创建二叉树(空格 表示此结点为空):
\n");
ﻩgetchar();
ﻩﻩCreateBiTree(T);
ﻩprintf(”\n按层遍历输出:
");
ﻩﻩLevelorder(T);
printf(”\n");
ﻩﻩﻩbreak;
ﻩﻩdefault:
return;
}}
6.函数间调用关系
main
InOrderTraverse_re
CreateBitree
PreOrderTraverse_re
InOrderTraverse
PreOrderTraverse
InOrderThreading
InOrderTraverse_Thr
Threading
Stack操作
调试分析
1、二叉树得分层遍历,开始时想用队列来做,但考虑到比较麻烦,因而改为数组模拟队列,简单易懂,课后可自行尝试用队列来做。
2. 在线索化二叉树时考虑到如果将两种存储结构分开将导致两个类型得指针不能互相传值,造成许多麻烦。
比较两种存储结构发现,线索二叉树比二叉树多了两个标志域LTag,Rtag。
于就是把两种存储结构合并为BiThrNode,并在建立二叉树时把LTag,Rtag均置为Link。
程序正常运行。
3、进入演示程序BiTree、cpp,完成编译,连接(即按下CtrlF5)进入演示界面,或直接打开执行文件BiTree、exe,产生如下图所示得界面:
1用户需根据用户提示信息操作,输入二叉树(以空格表示空结点),输入完成后按回车键,屏幕上打印出对应于该二叉树得各种遍历结果.如下图:
6、测试结果
输入:
-+a*b-cd -ef
屏幕输出:
中序递归遍历输出:
a+b*c—d
前序递归遍历输出:
+a*b-cd
中序非递归遍历输出:
a+b*c-d
前序非递归遍历输出:
+a*b-cd
按层遍历输出:
+a*b-cd
中序遍历线索化二叉树:
a+b*c-d
7、附录
BiTree、cpp
BiTree、exe
#include<stdio、h>
#include<stdlib、h>
#define QElemTypeBiTNode
#defineTElemTypechar
#defineOK 1
#defineOVERFLOW0
#defineERROR0
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
typedefenumPointerTag{Link,Thread};ﻩ//Link==0,指针,Thread==1,线索
typedef structBiTNode{
TElemType data;
struct BiTNode*lchild,*rchild;
ﻩPointerTag LTag ,RTag;
}BiTNode ,*BiTree,BiThrNode,*BiThrTree;ﻩ//二叉树
#defineQElemType BiTNode
#defineSElemTypeBiTree
typedef struct{
SElemType*base;
ﻩSElemType*top;
int stacksize;
}SqStack;
//全局变量
SqStackS;
BiThrTreepre;
BiThrTreei;
/*函数声明*/
intCreateBiTree(BiTree&T);ﻩﻩﻩ//创建二叉树
voidPreOrderTraverse_re(BiTree T,void(*print)(TElemTypee));ﻩ//先序递归遍历二叉树
void InOrderTraverse(BiTreeT,int (*print)(TElemTypee));ﻩ//中序非递归遍历二叉树
voidInOrderTraverse_re(BiTreeT,int (*print)(TElemTypee));ﻩ//中序递归遍历二叉树
voidPreOrderTraverse(BiTreeT,int(*print)(TElemTypee));ﻩ//先序非递归遍历二叉树
intprint(TElemType e);ﻩ//打印元素
void InitStack(SqStack&S);//栈得初始化
void Pop(SqStack&S,SElemType&e);
voidPush(SqStack&S,SElemType&e);
intStackEmpty(SqStackS);
int GetTop(SqStackS,SElemType&e);
void Levelorder(BiTreeT);
v