X-man

导航

实习三 树、二叉树及其应用 (题目:唯一地确定一棵二叉树 )

一、需求分析

   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

posted on 2013-04-07 20:03  雨钝风轻  阅读(768)  评论(0编辑  收藏  举报