二叉树实验报告

时间:2024.4.20

                            二叉树实验报告

姓名:张桂阳              学号:201011232023

一:需求分析

(1本程序需要用户自行输入二叉树(二叉树的数据可以是任何字符),用”#”表示空格,按回车键结束!

(2)程序功能:递归遍历二叉树,线索化二叉树,遍历线索化二叉树,二叉树去线索化。

(3)测试数据:ab##c##

二、概要设计

为实现本程序功能,应以二叉树结构存储二叉树,而为了实现非递归遍历二叉树的功能,应以带头节点的栈存储二叉树。

1、  二叉树的抽象数据类型定义

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,<ROOT,X< SPAN>1>∈H,且存在D1上的关系H1∈H;如Dr≠Ф,则Dr中存在唯一的元素xr,<ROOT,X< SPAN>r>∈H,且存在Dr上的关系Hr包含于H;H={<ROOT,X< SPAN>1>,<ROOT,X< SPAN>r>,H1,Hr};

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

基本操作:

                            InitBiTree(&T);

                                     操作结果:构造空二叉树T.

                            DestroyBiTree(&T);

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

                                     操作结果:销毁二叉树T.

                            CreateBiThrTree(&T);

                                     操作结果:先序构造二叉树T,Ltag和RTag初始置为Link.

PreOrderTraverse(T );

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

操作结果:先序递归遍历T。

                            InOrderTraverse(T);

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

操作结果:中序递归遍历T。

                            PostOrderTraverse(T);

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

操作结果:后序递归遍历T。

                            InOrderThreading(&ThrT, T);

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

                                     操作结果:建立头结点ThrT,并调用InThreading(T);函数。

                            InThreading(T);

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

                                     操作结果:中序线索化二叉树T;

                            InOrderTrasverse_Thr(T);

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

                                     操作结果:中序扫描线索化的二叉树。

}ADT BinaryTree

2、 栈的抽象数据类型定义

ADT Stack{

数据对象:d={ ai |ai∈elemset,i=1,2,3,……,n,n≥0}

数据关系:r={<ai-1,ai,)>| ai-1,ai ∈d, i=2,3,……,n}

                            约定a1为栈底,an 为栈顶。

基本操作:

(1)InitStack(&S)

操作结果:构造一个空栈S。

(2)DestroyStack(&S)

初始条件:栈S已存在。

操作结果:销毁栈S。

(3)ClearStack(&S)

初始条件:栈S已存在。。

操作结果:将栈清空为空栈。

(4)StackEmpty(&S)

初始条件:栈S已存在。

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

(5)StackLength(&S)

初始条件:栈S已存在。

操作结果:返回栈的长度(或者说深度)。

(6)GetTop(S,&e)

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

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

(7)Push(&S,e)

初始条件:栈S已存在。

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

(8)Pop(&S,&e)

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

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

(9)StackTraverse(S,visit())

初始条件:栈S已存在。

操作结果:遍历访问栈,一次对S的每个元素调用函

}ADT Stack

3、 程序包括6个模块

1)  主程序模块:

2)  创建二叉树;

3)  计算树的高度;

4)  递归遍历二叉树(先、中、后序);

5)  非递归遍历二叉树(先、中、后序);

6)  线索化二叉树(先、中序);

7)  二叉树去线索化(后序)

三、详细设计

1、 元素类型、结点类型

typedef struct BiTNode{

         TElemType data;

         struct BiTNode *lchild ,*rchild;

         PointerTag LTag , RTag;

}BiTNode , *BiTree , BiThrNode , *BiThrTree;          //二叉树存储结构

typedef struct{

         BiTNode *base;

         BiTNode *top;

         int stacksize;

}SqStack;            //栈存储结构  

2、 栈的实现

typedef struct{

         char *base;

         char *top;

         int stacksize;

}SqStack;            //栈类型

栈的基本操作设置如下:

void InitStack(Stack &S)

    //初始化,设S为空栈(S.top=NULL)

void DestroyStack(Stack &S)

   //销毁栈S,并释放所占空间

void ClearStack(Stack &S)

   //将S清为空栈

int StackLength(Stack S)

   //返回栈S的长度S.size

Status StackEmpty(Stack S)

   //若S为空栈(S.top==NULL),则返回TRUE;否则返回FALSE

Status GetTop(Stack S,ElemType e)

   //若栈S不空,则以e带回栈顶元素并返回TRUE,否则返回FALSE

Status Push(Stack&S,ElemType e)

  //若分配空间成功,则在S的栈顶插入新的栈顶元素e,并返回TRUE,

  //否则返回FALSE

void StackTraverse(Stack S,Status (*visit)(ElemType e))

  //从栈底到栈顶依次对S中的每个结点调用函数visit

栈的基本操作设置如下:

void InitStack(Stack &S)

    //初始化,设S为空栈(S.top=NULL)

void DestroyStack(Stack &S)

   //销毁栈S,并释放所占空间

void ClearStack(Stack &S)

   //将S清为空栈

int StackLength(Stack S)

   //返回栈S的长度S.size

Status StackEmpty(Stack S)

   //若S为空栈(S.top==NULL),则返回TRUE;否则返回FALSE

Status GetTop(Stack S,ElemType e)

   //若栈S不空,则以e带回栈顶元素并返回TRUE,否则返回FALSE

Status Push(Stack&S,ElemType e)

  //若分配空间成功,则在S的栈顶插入新的栈顶元素e,并返回TRUE,

  //否则返回FALSE

void StackTraverse(Stack S,Status (*visit)(ElemType e))

  //从栈底到栈顶依次对S中的每个结点调用函数visit

3、  主函数和其他函数的代码

int main()          //主函数

{

         printf("\t************\n\t*二叉树演示*\n\t************\n");

         BiTree T;

         BiThrTree Thrt;

         printf("\n创建二叉树(用#表示空格):\n");

         CreatBiTree(T);

         printf("树的高度为:%d",treedepth(T));

         printf("\n递归先序遍历:");

         PreOrderTraverse(T , Visit);

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

         InOrderTraverse(T , Visit);

         printf("\n递归后序遍历:");

         PostOrderTraverse(T , Visit);

    /*

printf("\n非递归先序遍历:");

         UnPreOrderTraverse(T , Visit);

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

    UnInOrderTraverse(T , Visit);*/

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

         InOrderThreading(Thrt , T);

         InOrderTraverse_Thr(Thrt , Visit);

         printf("\n后序递归去线索化并输出:");

         UnThreading(Thrt);

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

         PreOrderThreading(Thrt , T);

         printf("\n");

}

status PreOrderTraverse(BiTree T,status(*Visit)(TElemType e))  //递归先序遍历

{

         if(T)

         {

                   if(Visit(T->data))

                            if(PreOrderTraverse(T->lchild,Visit))

                                     if(PreOrderTraverse(T->rchild,Visit))

                                               return OK;

                                     return ERROR;

         }

         else

                   return OK;

}//PreOrderTraverse

status InOrderTraverse(BiTree T,status(*Visit)(TElemType e))  //递归中序遍历

{

         if(T)

         {

                   if(InOrderTraverse(T->lchild,Visit))

                            if(Visit(T->data))

                                     if(InOrderTraverse(T->rchild,Visit))

                                               return OK;

                                     return ERROR;

         }

         else return OK;

}//InOrderTraverse

status PostOrderTraverse(BiTree T,status(*Visit)(TElemType e))  //递归后序遍历

{

         if(T)

         {

                   if(PostOrderTraverse(T->lchild,Visit))

                            if(PostOrderTraverse(T->rchild,Visit))

                                     if(Visit(T->data))

                                               return OK;

                                     return ERROR;

         }

         else return OK;

}//PostOrderTraverse

status UnPreOrderTraverse(BiTree T,status(*Visit)(TElemType e))  //非递归先序遍历

{

         BiTree p;

         SqStack S;

         InitStack(S);

         p=T;

         while(p||!StackEmpty(S))

         {

                   if(p)

                   {

                            Push(S,p);

                            p=p->lchild;

                   }

                   else

                   {

                            Pop(S,p);

                            p=p->rchild;

                   }//else

         }//while

         return OK;

}//UnPreOrderTraverse

status UnInOrderTraverse(BiTree T,status(*Visit)(TElemType e))  //非递归中序遍历

{

         BiTree p;

         p=T;

         SqStack S;

         InitStack(S);

         while(p||!StackEmpty(S))

         {

                   if(p)

                   {

                            Push(S,p);

                            p=p->lchild;

                   }

                   else

                   {

                            Pop(S,p);

                            if(!Visit(p->data)) return ERROR;

                            p=p->rchild;

                   }//else

         }//while

         return OK;

}//UnInOrderTraverse

/*

status UnPostOrderTraverse(BiTree T,status(*Visit)(TElemType e))

//非递归后序遍历

{

         BiTree p;

         p=T;

         SqStack S;

         InitStack(S);

         int Tag[20];//栈,用于标识从左(0)或右(1)返回

         while(p||!StackEmpty(S))

         {

                   while(p)

                   {

                            Push(S,p);

                            Tag[S]=0;

                            p=p->lchild;

                           

                   }

                   while(!StackEmpty(S)&&Tag[S->top]==1)

                   {   Pop(S,p);

                            Visit(p->data);

                   }

                   if(!StackEmpty(S))  

                    {  Tag[S->top]=1;

                           p=

                  } p=p->rchild;

                            if(!Visit(p->data)) return ERROR;

                   }//elseVisit(p->data);

         }//while

         return OK;

}//UnPostOrderTraverse*/

status InOrderThreading(BiThrTree &Thrt,BiThrTree T)

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

{

         if(!(Thrt=(BiThrTree)malloc(sizeof(BiThrNode)))) exit(OVERFLOW);

         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;

                   InThreading(p->rchild);

         }

}//InThreading

void UnThreading(BiThrTree &Thrt)  //后序去线索化

{

         BiThrTree p=Thrt;

         if(p)

         {

                   if(p->LTag == Thread)

                   {

                            p->lchild = NULL;

                            p->LTag = Link;

                   }

                   if(p->LTag == Link && p->lchild) UnThreading(p->lchild);

                   if(p->RTag == Link && p->rchild)UnThreading(p->rchild);

                   if(p != i) Visit(p->data);

         }

}

status InOrderTraverse_Thr(BiThrTree T, status (*Visit)(TElemType e))

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

{

         BiThrTree p;

         p=T->lchild;

         while(p!=T)

         {

                   while(p->LTag==Link)

                            p=p->lchild;

                   if(!Visit(p->data))

                            return ERROR;

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

                   {

                            p=p->rchild;

                            Visit(p->data);

                   }

                   p=p->rchild;

         }

         return OK;

}

void PreOrderThreading(BiThrTree &Thrt,BiThrTree T)

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

{

         if(!(Thrt=(BiThrTree)malloc(sizeof(BiThrNode)))) exit(OVERFLOW);

         Thrt->LTag=Link;

         Thrt->RTag=Thread;//建头结点

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

         if(!T)

         Thrt->lchild=Thrt;

         else

         {

                   Thrt->lchild=T;

                   pre=Thrt;

                   PreThreading(T);//先序遍历进行先序线索化

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

                   Thrt->rchild=pre;

         }

         i=Thrt;

}

status PreOrderTraverse_Thr(BiThrTree T, status (*Visit)(TElemType e))

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

{

         BiThrTree p;

         p=T->lchild;

         while(p!=T)

         {

                   while(p->LTag==Link)

                            p=p->lchild;

                   if(!Visit(p->data))

                            return ERROR;

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

                   {

                            p=p->rchild; Visit(p->data);

                   }

                   p=p->rchild;

         }

         return OK;

}//PreOrderTraverse_Thr

void PreThreading(BiThrTree p)                //先序线索化

{

         if(p)

         {

                  

                   if(!p->lchild)

                   {

                            p->LTag = Thread;

                            p->lchild = pre;

                   }

                   if(!pre->rchild)

                   {

                            pre->RTag = Thread;

                            pre->rchild = p;

                   }

                   pre = p;

                   Visit(p->data);

                  

                   if(p->LTag==Link)

                            PreThreading(p->lchild);

                   if(p->RTag == Link)

                            PreThreading(p->rchild);

         }

}//PreThreading

四、调试分析

1、在线索化二叉树时,如果像书上把二叉树和线索二叉树的存储结构分开,则二叉树中的数据域不能传递到线索二叉树中(两个类型的指针不能互相赋值)。比较两种存储结构发现,线索二叉树比二叉树多了两个标志域LTag,Rtag。于是把两种存储结构合并为BiThrNode,并在建立二叉树时把LTag,Rtag均置为Link。程序正常运行。

2、本次实验报告所用的算法,书中均有具体算法演示,且易实现。

五、用户手册

1、本程序开发环境为c-free 5.0,运行环境为dos操作系统,执行文件为:二叉树.exe

2、运行该程序的二叉树.exe文件,产生如下图所示的界面:

  

3、按照提示输入二叉树(以”#”表示空格),如可以输入ab##c##。

4、输入完成后,按回车键。

5、屏幕上打印出对应于该二叉树的的各种遍历结果。

更多相关推荐:
实验六 二叉树实验报告(1)

实验四二叉树的操作班级:计算机1002班姓名:**学号:**完成日期:20XX.6.14题目:对于给定的一二叉树,实现各种约定的遍历。一、实验目的:(1)掌握二叉树的定义和存储表示,学会建立一棵特定二叉树的方法…

二叉树实验报告

实验六树和二叉树的操作一实验目的1进一步掌握树的结构及非线性特点递归特点和动态性2进一步巩固对指针的使用和二叉树的三种遍历方法建立方法二实验内容二叉树的实现和运算三实验要求1用CC完成算法设计和程序设计并上机调...

树和二叉树实验报告

树和二叉树一实验目的1掌握二叉树的结构特征以及各种存储结构的特点及适用范围2掌握用指针类型描述访问和处理二叉树的运算二实验要求1认真阅读和掌握本实验的程序2上机运行本程序3保存和打印出程序的运行结果并结合程序进...

二叉树基本操作--实验报告

宁波工程学院电信学院计算机教研室实验报告一实验目的1熟悉二叉树树的基本操作2掌握二叉树的实现以及实际应用3加深二叉树的理解逐步培养解决实际问题的编程能力二实验环境1台WINDOWS环境的PC机装有VisualC...

二叉树实验报告

二叉树实验报告问题描述1问题描述用先序递归过程建立二叉树存储结构二叉链表输入数据按先序遍历所得序列输入当某结点左子树或右子树为空时输入号如输入abcde得到的二叉树为编写递归算法计算二叉树中叶子结点的数目按凹入...

二叉树实验报告

数据结构课程设计报告专业计算机科学与技术班级3班姓名学号指导教师起止时间20xx1220xx1课程设计二叉树一任务描述二叉树的中序前序后序的递归非递归遍历算法应包含建树的实现任务设计一个程序实现二叉树的前序中序...

二叉树的遍历实验报告

二叉树的遍历实验报告一需求分析在二叉树的应用中常常要求在树中查找具有某种特征的结点或者对树中全部结点逐一进行某种处理这就是二叉树的遍历问题对二叉树的数据结构进行定义建立一棵二叉树然后进行各种实验操作二叉树是一个...

二叉树的遍历及其应用实验报告

实验报告题目二叉树的遍历及应用院系数学系专业数学与应用数学学号20xx114036姓名郭奇瑞一实验名称二叉树的遍历及应用二实验日期20xx年11月14日三实验要求编程实现二叉树的建立并对其进行遍历四实验目的1掌...

二叉树基本操作--实验报告

实验三二叉树的基本操作学院物理与电子学院班级电信1105班姓名刘岩学号1404110729一实验目的1熟悉二叉树的基本操作掌握二叉树的实现以及实际应用3加深对于二叉树的理解逐步培养解决实际问题的编程能力二实验环...

实验报告(二叉树)

仲恺农业工程学院实验报告纸信息科学与技术院系计算机专业144班数据结构与算法课一实验目的1掌握二叉树的特点以及的二叉链表存储结构2熟练掌握二叉树的各种操作如建立遍历查找和输出3利用已经掌握的知识进行实际应用二实...

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

数据结构课程实验报告注空间不够可以增加页码

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

数据结构实验报告课程数据结构实验名称二叉树实验院系电信学院专业班级计科104姓名学号一实验构思首先构造二叉树的存储结构用data存储当前节点的值分别用lchildrchild表示该节点的左右孩子然后应用BiTr...

二叉树实验报告(43篇)