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

时间:2024.4.20

实验报告


一、实验目的

1、熟悉二叉树树的基本操作。

2、掌握二叉树的实现以及实际应用。

3、加深二叉树的理解,逐步培养解决实际问题的编程能力。

二、实验环境

1台WINDOWS环境的PC机,装有Visual C++ 6.0。

三、实验内容

【问题描述】

       现需要编写一套二叉树的操作函数,以便用户能够方便的利用这些函数来实现自己的应用。其中操作函数包括:

1>     创建二叉树CreateBTNode(*b,*str):根据二叉树括号表示法的字符串*str生成对应的链式存储结构。

2>     输出二叉树DispBTNode(*b):以括号表示法输出一棵二叉树。

3>     查找结点FindNode(*b,x):在二叉树b中寻找data域值为x的结点,并返回指向该结点的指针。

4>     求高度BTNodeDepth(*b):求二叉树b的高度。若二叉树为空,则其高度为0;否则,其高度等于左子树与右子树中的最大高度加l。

5>     求二叉树的结点个数NodesCount(BTNode *b)   

6>     先序遍历的递归算法:void PreOrder(BTNode *b)   

7>     中序遍历的递归算法:void InOrder(BTNode *b)     

8>     后序遍历递归算法:void PostOrder(BTNode *b)

9>     层次遍历算法void LevelOrder(BTNode *b)

【基本要求】

实现以上9个函数。

主函数中实现以下功能:

创建下图中的树b

输出二叉树b

找到’H’节点,输出其左右孩子值

输出b的高度

输出b的节点个数

输出b的四种遍历顺序

上图转化为二叉树括号表示法为A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))

程序:

#include <stdio.h>

#include <malloc.h>

#define MaxSize 100

typedef char ElemType;

typedef struct node

{

       ElemType data;                           /*数据元素*/

       struct node *lchild;        /*指向左孩子*/

       struct node *rchild;        /*指向右孩子*/

} BTNode;

void CreateBTNode(BTNode *&b,char *str);//创建

BTNode *FindNode(BTNode *b,ElemType x);//查找节点

int BTNodeHeight(BTNode *b);//求高度

void DispBTNode(BTNode *b);//输出

int NodesCount(BTNode *b);//二叉树的结点个数

void PreOrder(BTNode *b);//先序遍历递归

void InOrder(BTNode *b);//中序遍历递归

void PostOrder(BTNode *b);//后序遍历递归

void LevelOrder(BTNode *b);//层次遍历

//创建

void CreateBTNode(BTNode *&b,char *str){

       BTNode *St[MaxSize],*p=NULL;

       int top=-1,k,j=0;

       char ch;

       b=NULL;

       ch=str[j];

       while(ch!='\0'){

              switch(ch){

              case '(':top++;St[top]=p;k=1;break;

              case ')':top--;break;

              case ',':k=2;break;

              default:p=(BTNode *)malloc(sizeof(BTNode));

                     p->data=ch;p->lchild=p->rchild=NULL;

                     if(b==NULL)

                            b=p;

                     else{

                            switch(k){

                            case 1:St[top]->lchild=p;break;

                            case 2:St[top]->rchild=p;break;

                            }

                     }

              }

              j++;

              ch=str[j];

       }

}

       //输出

       void DispBTNode(BTNode *b){

              if(b!=NULL){

                     printf("%c",b->data);

                     if(b->lchild!=NULL||b->rchild!=NULL){

                            printf("(");

                            DispBTNode(b->lchild);

                            if(b->rchild!=NULL)

                                   printf(",");

                            DispBTNode(b->rchild);

                            printf(")");

                     }

              }

       }

//查找节点

BTNode *FindNode(BTNode *b,ElemType x){

       BTNode *p;

       if(b==NULL)

              return b;

       else if(b->data==x)

              return b;

       else{

              p=FindNode(b->lchild,x);

              if(p!=NULL)

                     return p;

              else

                     return FindNode(b->rchild,x);

       }

}

     //求高度

     int BTNodeHeight(BTNode *b){

               int lchildh,rchildh;

               if(b==NULL)

                      return (0);

               else{

                      lchildh=BTNodeHeight(b->lchild);

                      rchildh=BTNodeHeight(b->rchild);

                      return(lchildh>rchildh)?(lchildh+1):(rchildh+1);

               }

        }

    //二叉树的结点个数

    int NodesCount(BTNode *b){

              if(b==NULL)

                     return 0;

              else

                     return NodesCount(b->lchild)+NodesCount(b->rchild)+1;

       }

    //先序遍历递归

       void PreOrder(BTNode *b){

              if(b!=NULL){

                     printf("%c",b->data);

                     PreOrder(b->lchild);

                     PreOrder(b->rchild);

              }

       }

       //中序遍历递归

       void InOrder(BTNode *b){

              if(b!=NULL){

                     InOrder(b->lchild);

                     printf("%c",b->data);

                     InOrder(b->rchild);

              }

       }

      

       //后序遍历递归

       void PostOrder(BTNode *b){

              if(b!=NULL){

                     PostOrder(b->lchild);

                     PostOrder(b->rchild);

                     printf("%c",b->data);

              }

       }

      

       //层次遍历

       void LevelOrder(BTNode *b){

              BTNode *p;

              BTNode *qu[MaxSize];

              int front,rear;

              front=rear=-1;

              rear++;

              qu[rear]=b;

              while(front!=rear){

                     front=(front+1)%MaxSize;

                     p=qu[front];

                     printf("%c",p->data);

                     if(p->lchild!=NULL){

                            rear=(rear+1)%MaxSize;

                            qu[rear]=p->lchild;

                     }

                     if(p->rchild!=NULL){

                            rear=(rear+1)%MaxSize;

                            qu[rear]=p->rchild;

                     }

              }

       }

void main()

{

       BTNode *b,*p,*lp,*rp;

       char str[]="A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))";//根据树形图改写成的

       //二叉树括号表示法的字符串*str

       //char str[100];scanf("%s",&str);//自行输入括号表示的二叉树

       CreateBTNode(b,str); //创建树b

       printf("\n");

       printf("输出二叉树:");//输出二叉树b

       DispBTNode(b);

       printf("\n");

       printf("'H'结点:");//找到'H'节点,输出其左右孩子值

       p=FindNode(b,'H');

       printf("\n");

       if (p!=NULL){  

              printf("左孩子节点的值");

              printf("%c",p->lchild->data);printf("\n");

              printf("右孩子节点的值");

              printf("%c",p->rchild->data);printf("\n");

              //此处输出p的左右孩子节点的值

       }

       printf("\n");

       printf("二叉树b的深度:%d\n",BTNodeHeight(b));//输出b的高度

       printf("二叉树b的结点个数:%d\n",NodesCount(b));//输出b的节点个数

       printf("\n");

      

       printf(" 先序遍历序列:\n");//输出b的四种遍历顺序

       printf("   算法:");PreOrder(b);printf("\n");

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

       printf("   算法:");InOrder(b);printf("\n");

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

       printf("   算法:");PostOrder(b);printf("\n");

    printf(" 层次遍历序列:\n");

       printf("   算法:");LevelOrder(b); printf("\n");

}

四、实验心得与小结

通过实验,我熟悉二叉树树的基本操作,掌握二叉树的实现以及实际应用。加深了对二叉树的理解,逐步培养解决实际问题的编程能力以及进一步了解了二叉树图转化为括号表示法。递归的使用,要注意,初始时的状态以及如何使用递归,注意普遍性,思考时从普通的开始。通过这次上机操作,让我明白书本上的程序一定要自己去调试,这样才能将书本程序与老师讲的内容融会贯通,达到温故而知新。

五、指导教师评议

成绩评定:                        指导教师签名:         


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


中南大学

数据结构实验报告

题    目         二叉树基本操作            

学生姓名                                        

联系电话                                               

指导老师                                                

专业班级                                        

完成时间          20##年11月25 日              

                             

    

一、  系统功能介绍…………………………………2

二、   需求分析………………………………………2

三、   概要设计………………………………………2

四、   详细设计………………………………………5

五、   调试分析………………………………………8

六、   使用说明………………………………………8

七、   测试结果………………………………………9

八、   心得体会………………………………………10

九、   附录(程序代码)……………………………11  

一、系统功能介绍

该程序是用C-Free编写的,主要功能是实现二叉树的定义和基本操作,包括定义二叉树的结构类型以及各个操作的具体函数的定义和主函数的定义。

各操作主要包括:初始化二叉树、按先序次序建立二叉树、检查二叉树是否为空、前序、中序、后序遍历树的方式、求树的深度、求树的结点数目、清空二叉树等九个对树的操作。

二、需求分析

    本程序由C-free工具编写完成了初始化,建立二叉树,检查树空与否,用前序、中序、后序遍历二叉树,求树的深度,求树的结点数目,清空二叉树等功能。

    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,<root,x1>∈H,,且存在D1上的关系H1H;若则中存在唯一的元素且存在上的饿关系

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

基本操作 P:

BinTree  BinTreeInit()

{

操作结果:构造空的二叉树

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

}

BinTree BinTreeCreat(BinTree &BT)

{

操作结果:用先序序列创建一个二叉树

初始条件:构造了空的二叉树

}

int BinTreeEmpty()

{

操作结果:返回0或1,即树的空与否

初始条件:二叉树存在

}

void PreBinTraverse(BinTree BT)

{

操作结果:按先序序列遍历输出二叉树

初始条件:二叉树存在

}

void InBinTraverse(BinTree BT)

{

操作结果:按中序序列遍历输出二叉树

初始条件:二叉树存在

}

void PastBinTraverse(BinTree BT)

{

操作结果:按后序序列遍历输出二叉树

初始条件:二叉树存在

}

int BinTreeDepth(BinTree BT)

{

操作结果:返回二叉树的深度

初始条件:二叉树存在

}

int BinTreeCount(BinTree BT)

{

操作结果:返回二叉树的结点个数

初始条件:二叉树存在

}

void BinTreeClear(BinTree &BT)

{

操作结果:清空释放二叉树的结点

初始条件:二叉树存在

}

}

四、详细设计

流程图

实现概要设计中定义的所有的数据类型,对每个操作给出伪码算法。对主程序和其他模块也都需要写出伪码算法。

typedef int DataType;

树节点类型定义

typedef struct BitNode{

    int data;

    struct BitNode *lchild,*rchild;

  }BitNode,*BitTree;1. 初始化二叉树,即把树根指针置空

1. Status BinTreeInit()

 { BitTree BT;

   BT=(BinTree)malloc(sizeof(BinNode));

   BT=NULL;

   return OK;

 }

2. 按先序次序建立一个二叉树

Status BinTreeCreat(BitTree &BT)

 {

   scanf("%d",&e);

   if(e=='0) BT=NULL;

   else

    { BT=(BinNode*)malloc(sizeof(BinNode));

       BT->data=e;              /*生成根结点*/

       BinTreeCreat(BT->lchild); /*构造左子树*/

       BinTreeCreat(BT->rchild); /*构造右子树*/

    }

   return OK;

 }

3. 检查二叉树是否为空

Status BinTreeEmpty(BitTree BT)

 { if(BT==NULL) return ERROR;

   else return OK;

 }

4. 前序遍历

Status PreBinTraverse(BitTree BT)

 { if(BT!=NULL)

   {printf("%d ",BT->data);/*DATA[i+1]=s->data;*/

    PreBinTraverse(BT->lchild);

    PreBinTraverse(BT->rchild);

}

Return OK;

 }

5. 中序遍历

Status InBinTraverse(BitTree BT)

 { if(BT!=NULL)

   {InBinTraverse(BT->lchild);

    printf("%d ",BT->data);

    InBinTraverse(BT->rchild);

   }

Return OK;

 }

6. 后序遍历

Status PastBinTraverse(BitTree BT)

 { if(BT!=NULL)

   {PastBinTraverse(BT->lchild);

    PastBinTraverse(BT->rchild);

    printf("%d ",BT->data);          

   }

Return OK;

 }

7. 求二叉树的深度

Int BinTreeDepth(BitTree BT){

    int i=1,j=1;

    if(BT==NULL)

    return ERROR;

    else

        {

        i=BinTreeDepth(BT->lchild);

        j=BinTreeDepth(BT->rchild);

  if(i>j)

  return(i+1);

  else

  return (j+1);

        }

  }

8. 求二叉树中所有结点数

BitTree BinTreeCount(BitTree BT)

 { if(BT==NULL) return 0;

   else

   return (BinTreeCount(BT->lchild)+BinTreeCount(BT->rchild)+1);

 }

9. 清除二叉树,使之变为空树

Status BinTreeClear(BitTree &BT){

    if(BT){

        if(BT->lchild)

        BinTreeClear(BT->lchild);

        if(BT->rchild)

        BinTreeClear(BT->rchild);

        free(BT);

        BT=NULL;

Return OK;

    }

  }

五.调试分析

   调试第一步:找出一些因为粗心而导致的错误如:少大括号,少逗号,字母打错,没有分清大小写,等等。

调试第二步:在这一步的调试中主要想谈谈函数BinTreeDepth(BitTree BT),BinTreeClear(BitTree &BT)这2个函数的调试。

       在BinTreeDepth(BitTree BT)函数中因为没有把最后的i和j加1所以最后的结果都少了一层,后来把i和j分别加上了1就可以了。在BinTreeClear(BitTree &BT函数中因为没有BT=NULL;而出现了错误后来改正了以后就好了。

六.结果测试

操作界面为

选择1后:

选择2:,分别输入1,2,3,0,0,4,5,0,0,0,0,建立一棵树。

选择3:

选择4:

选择5:

选择6:

选择7:

选择8:

选择9:

选择0:

七.心的体会

这个实验是所有的实验中难度最大的一个了,因为以前对树这种结构没有什么接触所以感觉比较陌生,在树的建立过程中虽然用的是递归算法但还是出现了错误,就是没有正确的领悟到结束的条件,在一个节点的结束时没有把它的左右孩子都置为空,后来经过仔细的思考才明白,只有把结点的左右孩子都置空才算把这个结点结束。

在遍历时因为用的是递归所以没有出现什么错误,一开始对遍历的递归不是很相信,不太相信那样 就可以把一棵树遍历出来,经过这个实验以后就没有怀疑了。

在后面的求结点和深度和销毁树中都用的是递归算法,所以经过这个实验后对递归这个工具有了很深的理解,从开始的懵懂慢慢变的清晰和理解了。

通过这个实验以后加深了对树这种新的结构的了解和理解。

八.源代码

# include<stdio.h>

# include<malloc.h>

# include<stdlib.h>

typedef struct BitNode{

    int data;

    struct BitNode *lchild,*rchild;

  }BitNode,*BitTree;

BitTree BitTreeInit(){

    BitTree BT;

    BT=(BitNode*)malloc(sizeof(BitNode));

    BT=NULL;

    return BT;

 }

BitTree BitTreeCreat(BitTree &BT){

    int ch;

    printf("请输入节点的内容,输入0时结束建立!\n");

    scanf("%d",&ch);

    if(ch==0)

    BT=NULL;

    else{

        BT=(BitTree)malloc(sizeof(BitNode));

        BT->data=ch;

        BitTreeCreat(BT->lchild);

        BitTreeCreat(BT->rchild);

        }

        return BT;

 }

void BitTreeEmpty(BitTree BT){

    if(BT==NULL)

    printf("树为空!\n");

    else

    printf("树非空!\n");

  }

void PreOrderTraverse(BitTree BT){

        if(BT!=NULL){

            printf("树结点的内容为:%d\n",BT->data);

            PreOrderTraverse(BT->lchild);

            PreOrderTraverse(BT->rchild);

        }

  }

void InOrderTraverse(BitTree BT){

    if(BT!=NULL){

           InOrderTraverse(BT->lchild);

           printf("树结点的内容为:%d\n",BT->data);

           InOrderTraverse(BT->rchild);

    }

  }

void  PostOrderTraverse(BitTree BT){

    if(BT!=NULL){

        PostOrderTraverse(BT->lchild);

        PostOrderTraverse(BT->lchild);

        printf("树结点的内容为:%d\n",BT->data);

    }

   }

int count(BitTree BT){

    if(BT==NULL)

    return 0;

    else

    return(count(BT->lchild)+count(BT->rchild)+1);

  }

int BinTreeDepth(BitTree BT){

    int i=1,j=1;

    if(BT==NULL)

    return 0;

    else

        {

        i=BinTreeDepth(BT->lchild);

        j=BinTreeDepth(BT->rchild);

  if(i>j)

  return(i+1);

  else

  return (j+1);

        }

  }

void BinTreeClear(BitTree &BT){

    if(BT){

        if(BT->lchild)

        BinTreeClear(BT->lchild);

        if(BT->rchild)

        BinTreeClear(BT->rchild);

        free(BT);

        BT=NULL;

    }

  }

main(){

    int i=1,j,l;

    BitTree BT;

    while(i!=0){

        printf("-----------------欢迎使用-------------------\n");

        printf("请选择要进行的操作\n");

        printf("1.初始化一棵树 2.建立一棵树 3.判断树是否为空\n");

        printf("4.按前序遍历树 5.按中序遍历树 6.按后序遍历树\n");

        printf("7.求树的深度   8.求树的结点数 9.把树清空\n");

        printf("0.退出操作界面\n");

        printf("-----------------谢谢使用-------------------\n");

        scanf("%d",&j);

        switch(j){

            case 1:BT=BitTreeInit();printf("树已经初始化!\n");break;

            case 2:BitTreeCreat(BT);break;

            case 3:BitTreeEmpty(BT);break;

            case 4:PreOrderTraverse(BT);break;

            case 5:InOrderTraverse(BT);break;

            case 6:PostOrderTraverse(BT);break;

            case 7:l=BinTreeDepth(BT);printf("树的深度为:%d\n",l);break;

            case 8:l=count(BT);printf("树的结点数为:%d\n",l);break;

            case 9:BinTreeClear(BT);printf("树已经清空!\n");break;

            case 0:exit(0);

        }

    }

}

更多相关推荐:
化学实验基本操作的练习

化学实验基本操作唐荣德1某学生采用以下方法清洗实验仪器用稀HNO3清洗做过银镜实验的试管用NaOH溶液清洗盛过苯酚的试管用盐酸清洗长期盛放石灰水的试剂瓶用乙醇清洗做过酚醛树脂的试管这位同学各项操作中正确的是DA...

化学实验基本操作实验报告单

学生实验活动记录和报告实验一化学实验简单的基本操作姓名年级日期

化学实验报告 实验__化学实验基本操作

实验报告姓名:班级:同组人:自评成绩:项目:化学实验基本操作课程:学号:一、实验目的1.熟悉实验室规则,安全守则及意外事故处理。2.学会玻璃仪器正确的洗涤和干燥方法。3.掌握简单玻璃工操作的基本要领,学会制作玻…

化学实验基本操作实验报告单

实验一化学实验基本操作姓名年级日期任课教师实验目的1认识化学实验常用仪器2掌握药品的取用加热等基本操作实验仪器及药品试管镊子试管夹药匙量筒酒精灯食盐大理石等分析加热试管后发现试管破裂的可能原因

生物化学实验基本操作-实验报告

生物化学实验基本操作一实验目的1熟悉化学类实验室的基本常识规则安全及防护知识2掌握基本实验操作及常用仪器的使用方法3通过实际操作进一步掌握理论知识能独立完成真个实验的设计操作及计算二实验仪器与试剂1实验器材仪器...

凉风中学九年级化学实验基本操作实验报告

实验一化学实验基本操作1班级姓名实验目的1认识初中化学实验中常用仪器2了解它们的用途使用注意事项3培养学生实验操作能力并对学生进行安全教育实验器材试管试管夹酒精灯铁架台铁圈铁夹圆底烧瓶集气瓶燃烧匙石棉网蒸发皿长...

化学实验基本操作方法

化学实验基本操作方法,内容附图。

无机化学实验操作规范

无机化学实验操作规范目录化学实验的基本要求和学习方法1无机化学实验操作规范3一3一般无机化学实验仪器的使用二仪器的一般洗涤与干燥3三酒精灯和酒精喷灯的使用5四玻璃管的切割与熔光7五塞子的选择和钻孔8六托盘天平的...

高中化学:1.1《化学实验基本方法》教案+随堂练习(新人教版必修1)

第一节化学实验基本方法第1课时教学目标1树立安全意识初步养成良好的实验习惯并能识别一些化学品安全标识2通过识别一些化学品安全标识提高学生的学习兴趣3使学生树立严谨的科学探究习惯教学重点难点重点树立实验安全意识能...

高中化学必修一第一节 化学实验基本方法 教学过程讲义及习题(超具体超有用)

教案教案

化学实验报告的撰写

化学实验报告的撰写一化学实验内容很多也很广泛化学实验报告一般是根据实验步骤和顺序从七方面展开来写的1实验目的即本次实验所要达到的目标或目的是什么使实验在明确的目的下进行2实验日期和实验者在实验名称下面注明实验时...

高一化学:1.1《化学实验基本方法》教案(新人教版必修1).doc

七彩教育网教学资源免费共享平台分享资源价值第一章从实验学化学第一节化学实验基本方法一教材分析1教学内容分析化学实验基本方法在强调化学实验安全性的基础上通过粗盐的提纯实验复习过滤和蒸发等操作蒸馏则是在初中简易操作...

化学实验基本操作实验报告(23篇)