数据结构实验之二叉树四:(先序中序)还原二叉树

Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description
给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度。

Input
输入数据有多组,每组数据第一行输入1个正整数N(1 <= N <= 50)为树中结点总数,随后2行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区分大小写)的字符串。

Output
输出一个整数,即该二叉树的高度。

Sample Input
9
ABDFGHIEC
FDHGIBEAC
Sample Output
5

(http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/3343.html)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/* 此题为二叉树部分遍历基础题,根据先序序列和中序序列来建立二叉树,
前序遍历序列的第一个节点就是根节点,并在中序序列中找到此节点,那么
中序序列的左边所有节点便是根节点的左子树部分,右边为右子树部分,因
此,可以用递归分而治之。*/
typedef struct node
{
    char data;
    struct node *lchild,*rchild;

}tree; //用typedef 为复杂的声明定义简单的别名,
      //即把结构体的名字给起名为 tree。
tree *creat(char *pre,char *in,int len)
{/* 每个子树的先序序列的第一个节点为子树的根,向后移动子树的中序序列
    ,依旧使用和上述方法一样的套路,找到中序序列中的根节点,便可分开
    得到左右子树,因此可以使用递归。*/
    tree  *root;
    if(len<=0)
    return NULL;//或者 root=NULL;
    root= new tree;// 和root = (tree *)malloc(sizeof(tree));一样;
    root->data=*pre;//此为把先序序列的第一个节点指定 为当前子树的根;
    char *p;//可理解为移动下标或者指针。
    for(p=in;p!=NULL;p++)
    {
        if(*p==*pre)
            break;
    }                 //这一步为在中序序列中查找到当前根节点。
    int lon=p-in;  //这就可以求出左子树节点的个数了;
    root->lchild=creat(pre+1,in,lon);//这个为创建左子树啊,递归,和参数里的意思一样。
    root->rchild=creat(pre+1+lon,p+1,len-lon-1);//这一块要充分理解,因为我们要的是创建右子树的
                                                //首地址,所以要计算好首地址所在的位置,以及剩余
                                                //的序列长度为右子树部分。
    return  root;//日,提交了两次都WA,原来忘了返回 。。。。。bitch。
}
int PostTreeDepth(tree *root )
{ /*此为求二叉树深度的函数,递归定义如下:若根为空,则高度为0,若非空,就去求就好
    ,而且求高度是基于后序的思想,不能用前序和中序那样的格式去写,因为高度未知。*/
    int hl,hr,max;
    if(root!=NULL)
    {
        hl=PostTreeDepth(root->lchild);//求左子树高度;
        hr=PostTreeDepth(root->rchild);//求右子树高度;
        max = hl > hr ? hl : hr;
        return  max + 1; //最终二叉树的高度为左右子树中较大的深度加1;

    }
    else
        return 0;

}
int main()
{
    int n;
    tree *root;
    char s1[55],s2[55];
    while(~scanf("%d",&n))
    {
        scanf("%s",s1);
        scanf("%s",s2);
        //可以char *pre,*in;
        //让pre = s1;
        // in = s2;
        root=creat(s1,s2,n);
        printf("%d\n",PostTreeDepth(root));
    }
    return 0;
}
方法二:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node
{
    char data;
    struct node *lchild,*rchild;

}tree;
tree *creat(char a[],char b[],int len)
{/* 另一种通俗易懂的方法,改为用数组写,数组的名称就为
    他的首地址,因此这个可以简单一些。*/
    tree  *root;
    if(len<=0)
    return NULL;
    root= new tree;
    root->data=a[0];
    char *p;
    for(p=b;p!='\0';p++)
    {
        if(*p==a[0])
            break;
    }
    int l=p-b;
    root->lchild=creat(a+1,b,l);
    root->rchild=creat(a+1+l,p+1,len-l-1);
    return  root;
}
int PostTreeDepth(tree *root )
{
    int hl,hr,max;
    if(root!=NULL)
    {
        hl=PostTreeDepth(root->lchild);
        hr=PostTreeDepth(root->rchild);
        max = hl > hr ? hl : hr;
        return  max + 1;

    }
    else
        return 0;

}
int main()
{
    int n;
    tree *root;
    char s1[55],s2[55];
    while(~scanf("%d",&n))
    {
        scanf("%s",s1);
        scanf("%s",s2);
        root=creat(s1,s2,n);
        printf("%d\n",PostTreeDepth(root));
    }
    return 0;
}
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值