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

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

【实验目的】

内容:二叉树基本操作的编程实现

要求:

二叉树基本操作的编程实现(2学时,验证型),掌握二叉树的建立、遍历、插入、删除等基本操作的编程实现,也可以进一步编程实现查找等操作,存储结构主要采用顺序或链接结构。也鼓励学生利用基本操作进行一些应用的程序设计。

【实验性质】

验证性实验(学时数:2H)

【实验内容】

以下的选题都可以作为本次实验的推荐题目

  1. 建立二叉树,并以前序遍历的方式将结点内容输出
  2. 将一个表示二叉树的数组结构转换成链表结构
  3. 将表达式二叉树方式存入数组,以递归方式建立表达式之二叉树状结构,再分别输出前序、中序及后序遍历结果,并计算出表达式之结果。

【注意事项】

1.开发语言:使用C。

2.可以自己增加其他功能。

【实验分析、说明过程】                                                 

非递归实现的先序遍历

定义栈s,top表示栈顶指针 定义指向二叉树的指针p

如果是空二叉树,遍历结束

不是空二叉树则循环

    While循环 当前指针p入栈 访问当前二叉树根节点  指针指向p的左孩子结点

    如果栈空时结束 否则弹出栈顶元素  指针指向p的右孩子结点

非递归实现的中序遍历

定义栈s,top表示栈顶指针 定义指向二叉树的指针p

如果是空二叉树,遍历结束

不是空二叉树则循环

    While循环 当前指针p入栈 指针指向p的左孩子结点

    如果栈空时结束 否则弹出栈顶元素 访问当前二叉树根节点 指针指向p的右孩子结点

【思考问题】

  1. 二叉树是树吗?它的定义为什么是递归的?

二叉树是树的一种特殊形式。

二叉树由根节点、左子树和右子树组成,而左子树和右子树也是一棵二叉树,它们的定义与原二叉树的定义相同,因此可以使用递归的方式来定义二叉树。

  1. 三种根序遍历主要思路是什么?

先序遍历:先访问根节点 再访问左子树 最后访问右子树

中序遍历:先访问左子树 再访问根节点 最后访问右子树

后序遍历:先访问左子树 再访问右子树 最后访问根节点

  1. 如果不用遍历算法一般启用什么数据结构实现后序遍历?

使用递归:
   递归的思想就是对于每个节点,先递归遍历其左子树,然后递归遍历其右子树,最后访问该节点

  1. 举出二叉树的应用范例?

文件系统  编译器  哈夫曼树

实验小结 (总结本次实验的重难点及心得、体会、收获)

本次实验学习了二叉树的遍历,创建

二叉树是一种特殊的树,遍历有先序中序和后序三种,以及递归和非递归方式。

【附录-实验代码】

基础篇

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

    preorder(p->lchild);

    preorder(p->rchild);

    inorder(p->lchild);

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

    inorder(p->rchild);

    postorder(p->lchild);

    postorder(p->rchild);

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

提高篇

#include<stdio.h>

#include<stdlib.h>

#include<conio.h>

#define MAXSIZE 100

typedef char elemtype;

typedef struct  bitree

{  

    elemtype data;

    struct bitree *lchild,*rchild;

}BTREE;

BTREE *create()

{//非递归创建二叉树

   BTREE *q[100]; //定义q数组作为队列存放二叉链表中结点,100为最大容量

   BTREE *s;                //二叉链表中的结点

   BTREE *root ;            //二叉链表的根指针

   int front=1,rear=0,i;      //定义队列的头、尾指针

   char ch;                 //结点的data域值

   root=NULL;

   for(i=0;i<100;i++)

       q[i]=NULL;

   printf("请按层次依次输入二叉树中的结点:\n");

   printf("空结点以逗号代替,以#号结束!\n");

   ch=getchar();

   while(ch!='#')     //输入值为#号,算法结束

    {

       s=NULL;

       if(ch!=',')    //输入数据不为逗号,表示不为虚结点,否则为虚结点

        {

           s=(BTREE *)malloc(sizeof(BTREE));   s->data=ch;

           s->lchild=NULL;                     s->rchild=NULL;

        }

       rear++;

       q[rear]=s;    //新结点或虚结点进队

       if(rear==1)

         root=s;

       else

        {

          if((s!=NULL)&&(q[front]!=NULL))

           {

             if(rear%2==0)

               q[front]->lchild=s;   //rear为偶数,s为双亲左孩子

             else

               q[front]->rchild=s;   //rear为奇数,s为双亲右孩子

           }         

          if(rear%2==1) front++;    //出队

        } 

       ch=getchar();      

    }

   return root;

}

void preorder(BTREE *root)

{//非递归实现的先序遍历

  BTREE *s[MAXSIZE],*p=root;

  int top=-1;

  if(p==NULL) return;

  do{

    while(p!=NULL)

    {

        if(top>=MAXSIZE-1)

        {

            printf("栈溢出\n");

        }

        s[++top]=p;

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

        p=p->lchild;

    }

    if(top==-1) return;

    else

    {

        p=s[top--];

        p=p->rchild;

    }

  }while(p!=NULL||top!=-1);

}

void inorder(BTREE *root)  

{//非递归实现的中序遍历

  BTREE *s[MAXSIZE],*p=root;

  int top=-1;

  if(p==NULL) return;

  do{

    while(p!=NULL)

    {

        if(top>=MAXSIZE-1)

        {

            printf("栈溢出\n");

        }

        s[++top]=p;

        p=p->lchild;

    }

    if(top==-1) return;

    else

    {

        p=s[top--];

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

        p=p->rchild;

    }

  }while(p!=NULL||top!=-1);

}

void postorder(BTREE *root)

{//非递归实现的后序遍历 

  BTREE *p,*s1[100];             //s1栈存放树中结点

  int s2[100],top=0,b;           //s2栈存放进栈标志

  p=root;

  do

   {

     while(p!=NULL)

        {

         s1[top]=p;

         s2[top++]=0;    //第一次进栈标志为0

         p=p->lchild;

        }

     if(top>0)

     {

      b=s2[--top];

      p=s1[top];

      if(b==0)

       {

          s1[top]=p;

          s2[top++]=1;  //第二次进栈标志为0

          p=p->rchild;

        }

      else

        {

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

          p=NULL;

        }

     }

   }while(top>0);

}

void  lorder(BTREE  *root)

{//非递归实现的层次遍历 

    BTREE *q[MAXSIZE],*p;      // maxsize为最大容量

    int f,r;                   // f,r类似于头尾指针

    q[1]=root;

    f=r=1;

    while(f<=r)

        {

         p=q[f];

         f++;                 //出队

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

         if(p->lchild!=NULL)

           {

            r++;

            q[r]=p->lchild;

           }        //入队

         if(p->rchild!=NULL)

           {

            r++;

            q[r]=p->rchild;

           }   //入队

        }

}

void showmenu()

{//显示菜单

    printf("    欢迎使用二叉树操作演示小软件\n");

    printf("\t1、创建二叉树\n");

    printf("\t2、先序遍历二叉树\n");

    printf("\t3、中序遍历二叉树\n");

    printf("\t4、后序遍历二叉树\n");

    printf("\t5、层次遍历二叉树\n");

    printf("\t6、退出程序\n"); 

}

int main()

{

    BTREE *root=NULL;

    int no;

    while(1)

    {

        showmenu();

        printf("   请输入你的选择:");

        scanf("%d",&no);

        fflush(stdin);//清除键盘缓冲区

        switch(no)

        {

          case 1:root=create();

                printf("二叉树创建成功,按任意键继续…\n");

                getch();

                system("cls");

                break;

          case 2:printf("二叉树先序遍历结果为:\n");

                preorder(root);

                printf("\n");

                system("pause");

                system("cls");

                break;

          case 3:printf("二叉树中序遍历结果为:\n");

                inorder(root);

                printf("\n");

                system("pause");

                system("cls");

                break;

          case 4:printf("二叉树后序遍历结果为:\n");

                postorder(root);

                printf("\n");

                system("pause");

                system("cls");

                break;

          case 5:printf("二叉树层次遍历结果为:\n");

                lorder(root);

                printf("\n");

                system("pause");

                system("cls");

                break;

          case 6:return 0;

          default:

                printf("你的输入有误,请从新输入!\n");                

        }

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值