zoukankan      html  css  js  c++  java
  • 实习三 树、二叉树及其应用 (题目:唯一地确定一棵二叉树 )

    一、需求分析

       1.问题描述:如果给出了遍历二叉树的前序序列和中序序列,则可以构造出唯一的一棵二叉树。试编写实现上述功能的程序。

       2.基本要求: 已知一棵二叉树的前序和中序序列,试设计完成下列任务的一个

        算法:

              (1)构造一棵二叉树;

              (2)证明构造正确(即分别以前序和中序遍历该树,将得到的结

        果与给出的序列进行比较)。

       3.测试数据: 前序序列为ABDEGCFHIJ,中序序列为DBGEAHFIJC。

    https://wenku.baidu.com/view/7b6254df640e52ea551810a6f524ccbff121cab5
    #include<stdio.h>
    #include<malloc.h>
    #include<string.h>
    typedef char DataType;
    typedef struct Node
    {
        DataType data;
        struct Node *leftChild;
        struct Node *rightChild;
    }*BiTreeNode;      
    void PrintTree(BiTreeNode root,int n)  //树的凹形输出 
    {
        int i;
        if(root==NULL)return;
        PrintTree(root->rightChild,n+1);
        for(i=0;i<n-1;i++)printf("   ");
        if(n>0)
        {
            printf("---");
            printf("%c\n",root->data);
        }
            if(n==0)
        {
            printf("-");
            printf("%c\n",root->data);
        }
        PrintTree(root->leftChild,n+1); 
    } 
    void Initiate(BiTreeNode *root)      // 树的初始化 
    {
        *root=(BiTreeNode)malloc(sizeof(struct Node));
        (*root)->leftChild=NULL;
        (*root)->rightChild=NULL;
    }
     void PreOrder(BiTreeNode bt)       //前序遍历以bt为根结点指针的二叉树
     {  
        if (bt==NULL) return;
        printf("%c",bt->data);
        PreOrder(bt->leftChild);  
        PreOrder(bt->rightChild);
     }
    void InOrder(BiTreeNode bt)         //中序遍历以bt为根结点指针的二叉树
     {  
        if (bt==NULL) return;
        InOrder(bt->leftChild);
           printf("%c",bt->data);
        InOrder(bt->rightChild);
     }
    int Creattree(DataType *pre,DataType *in,int al,BiTreeNode &T)
     {                                   //树的创建 
         int k;
         DataType *i;
        if(al<=0)
        {
            T=NULL;
            return 0;
        }
        for(i=in;i<in+al;i++)           //查找根结点 
        if(*pre==*i)
        {
            k=i-in;  //k为根结点在中序序列中相对头结点的距离 
            T=(BiTreeNode)malloc(sizeof(struct Node));      
            T->data=*i;
            break;    
        };    
        Creattree(pre+1,in,k,T->leftChild);  //建立左子树   
        Creattree(pre+k+1,in+k+1,al-k-1,T->rightChild);//建立右子树  
     }
      
    int main()
    {
        DataType a[50],b[50];
        int al,bl; 
        int k=0;    
        BiTreeNode root;
        printf("请输入前序遍历:"); 
        scanf("%s",&a);
        printf("请输入中序遍历:"); 
        scanf("%s",&b);
        al=strlen(a);
        bl=strlen(b);
        Initiate(&root);              
        if(al==bl)Creattree(a,b,al,root);    
           else k=1;
        if(k){printf("序列不匹配");printf("\n");} 
           else{ PrintTree(root,0);PreOrder(root);printf("\n"); InOrder(root);printf("\n");}        
    }

                                                                  实习三 树、二叉树及其应用

         题目:唯一地确定一棵二叉树                 实习时间:2012/10/30

    一、需求分析

       1.问题描述:如果给出了遍历二叉树的前序序列和中序序列,则可以构造出唯一的一棵二叉树。试编写实现上述功能的程序。

       2.基本要求: 已知一棵二叉树的前序和中序序列,试设计完成下列任务的一个

        算法:

              (1)构造一棵二叉树;

              (2)证明构造正确(即分别以前序和中序遍历该树,将得到的结

        果与给出的序列进行比较)。

       3.测试数据: 前序序列为ABDEGCFHIJ,中序序列为DBGEAHFIJC。

    二、设计

    二、      1. 设计思想

    二、        (1)存储结构

    二、         用两个一维数组A和B分别存放前序和中序序列。 

            (2)主要算法基本思想

              ①将前序和中序序列分别读入数组A和B。

              ②根据定义,前序序列中第一个元素一定是树根,在中序序列中该

          元素之前的所有元素一定在左子树中,其余元素则在右子树中。所以,

          首先从数组A中取出第一个元素A[0]作根结点,然后在数组B中找到A[0],

          以它为界,在其前面的是左子树中序序列,在其后面的是右子树中序序列。

              ③若左子树不为空,沿前序序列向后移动,找到左子树根结点,转②。

              ④左子树构造完毕后,若右子树不为空,沿前序序列向后移动,找到

          右子树根结点,转②。

              ⑤前序序列中各元素取完则二叉树构造完毕。

              ⑥对二叉树进行前序和中序遍历,并将结果分别与数组A和B进行

          比较,若相同,则证明二叉树构造正确。

        2. 设计表示

            (1)函数调用关系图

              main→StackPush→QueueAppend→QueueAd→StackPop→QueueGet

            (2)函数接口规格说明    

    void PrintTree(BiTreeNode root,int n)  //以root为根节点的树凹形输出

    void Initiate(BiTreeNode *root)      // 以root为根节点的树初始化

    void PreOrder(BiTreeNode bt)       //前序遍历以bt为根结点指针的二叉树

    void InOrder(BiTreeNode bt)         //中序遍历以bt为根结点指针的二叉树

    int Creattree(DataType *pre,DataType *in,int al,BiTreeNode &T)  //用前序序列和中序序列构造以T为根节点的树,其中pre,in分别为前序序列和中序序列的首地址,al为中序序列的长度。

    3. 实现注释    (即各项功能的实现程度)

          (1)必须正确输入前序序列和中序序列;

          (2)若前序序列和中序序列的长度不一样,则输出“不匹配”;

    (3)若前序序列和中序序列的长度一样,但不能构成一棵二叉树,则程序会出错,即程序缺乏健壮性。     

    4. 详细设计    (即主要算法的细化。略,见上课笔记)

    【1】void Initiate(BiTreeNode *root)      // 树的初始化

    {

      *root=(BiTreeNode)malloc(sizeof(struct Node));

      (*root)->leftChild=NULL;

      (*root)->rightChild=NULL;

    }

    【2】int Creattree(DataType *pre,DataType *in,int al,BiTreeNode &T)

     {                                   //树的创建

            int k;

            DataType *i;

        if(al<=0)

        {

            T=NULL;

            return 0;

        }

      for(i=in;i<in+al;i++)           //查找根结点

        if(*pre==*i)

      {

          k=i-in;  //k为根结点在中序序列中相对头结点的距离

            T=(BiTreeNode)malloc(sizeof(struct Node));     

            T->data=*i;

            break;   

      };    

        Creattree(pre+1,in,k,T->leftChild);  //建立左子树  

        Creattree(pre+k+1,in+k+1,al-k-1,T->rightChild);//建立右子树 

     }

    【3】void PrintTree(BiTreeNode root,int n)  //树的凹形输出

    {

      int i;

      if(root==NULL)return;

      PrintTree(root->rightChild,n+1);

      for(i=0;i<n-1;i++)printf("   ");

      if(n>0)

      {

             printf("---");

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

      }

             if(n==0)

      {

             printf("-");

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

      }

      PrintTree(root->leftChild,n+1);

    }

    【4】void PreOrder(BiTreeNode bt) //前序遍历以bt为根结点指针的二叉树

     { 

        if (bt==NULL) return;

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

        PreOrder(bt->leftChild); 

        PreOrder(bt->rightChild);

     }

    【5】void InOrder(BiTreeNode bt) //中序遍历以bt为根结点指针的二叉树

     { 

        if (bt==NULL) return;

        InOrder(bt->leftChild);

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

        InOrder(bt->rightChild);

     }

    三、调试分析

          1.调试过程中遇到的主要问题是如何解决的;

    调试过程中存在少许C语言的基础语法错误,经独立仔细观察和调试修改正确,最大的难题是创建树时,递归调用自身函数的中序序列数组下标表示。在自己独立多次修改下,终于完成。     

    2.对设计和编码的回顾讨论和分析;

    总的来说,这个程序写的比较顺畅,毕竟老师已经把整个算法思路都已给出。但是,每次写程序都有的感觉是,对好多的基本语法还不是特别熟悉,写到某些刚学的数据结构知识时得在书中找代码和代码思想。所以,应该多练习才好。

    3.时间和空间复杂度的分析;

    【1】创建二叉树的函数: 时间O(n),空间O(n)

           【2】二叉树的凹形输出函数:时间O(n),空间O(1)。

          4.改进设想;

           【1】在递归创建二叉树的算法中,若能判断前序序列和中序序列是否能构成二叉树,这样就能增强程序的健壮性。向同学请教过,也找了部分电子和书本知识,但均未发现解决办法。

           【2】重新设计创建二叉树的非递归算法,这样能较好的解决程序的健壮性问题。但非递归算法过程较复杂。

    5.经验和体会等。

    多动手编程,才能熟练灵活的掌握C语言基础知识,才能更好的理解掌握数据结构的精髓。从而避免基础语法错误,让代码变得更简洁高效。如此才能准确高效的解决问题。在今后的编程过程中要更注重代码整体设计的提纲记录,用更多的注释。

    四、用户手册(即使用说明)

       仅需按照提示正确输入前序序列和中序序列。若出错,则表明前序序列和中序序列不能构成一颗二叉树。

    五、运行结果

    运行环境:C-free

    【1】    前序序列为ABDEGCFHIJ,中序序列为DBGEAHFIJC。

    【2】    前序序列为ABC,中序序列为BAC。

    【3】    前序序列为ABCEFDGH,中序序列为ECFBGDHA。

    【4】    若长度不一:前序序列为ABDEGCFHIJ,中序序列为DBGEAHFIJCZ。

    【5】    若前序序列和中序序列的长度一样,但不能构成一棵二叉树。前序序列为ABC,中序序列为CAB。

    【6】    若前序序列和中序序列的长度一样,但不能构成一棵二叉树。前序序列为ABC,中序序列为GHJ。

    六、源程序清单

    https://wenku.baidu.com/view/7b6254df640e52ea551810a6f524ccbff121cab5

  • 相关阅读:
    批量 kill mysql 中运行时间长的sql
    第三方支付过程中session失效问题
    Maven常用命令:
    根据Request获取客户端IP
    MySQL之alter语句用法总结
    转:Redis使用认证密码登录
    Git添加远程库
    输入一个三位数x,它的个位数为a,十位数为b,百位数为c,请把它的各个位数分离出来并输出。
    20161129 计算95除以55,商是多少,余数是多少?(商和余数要求分两行显示)
    20161128 已知小明同学其中考试成绩,数学97.5分,语文94.5分,英语95.5分,求小明同学的三科总成绩(结果保留一位小数)。
  • 原文地址:https://www.cnblogs.com/XDJjy/p/3005991.html
Copyright © 2011-2022 走看看