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

Description

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

Input

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

Output

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

Sample

Input

9 
ABDFGHIEC
FDHGIBEAC

Output

5

二叉树的高度和深度的区别

高度和深度是相反的表示,深度是从上到下数的,而高度是从下往上数。

沿根节点r到该节点v的通路上最长简单路径边的节点数目,称作v 的深度(depth),记作depth(v)。

依据深度排序,可对所有节点做分层归类。特别地,约定根节点的深度 depth(root) = 1,

故属于第1层。

沿该节点v到该根节点r的通路上最长简单路径边的节点数目,记作height(v)。

树T中所有节点深度的最大值称作该树的高度(height),记作height(T)。空树的高度为0。

注意:这里边的条数是规定根节点的深度和叶子节点的高度是1;

下面这棵二叉树的高度为3。

所以树的深度和高度是相等的,而对其他节点来说深度和高度不一定相等。

如 B和C节点深度都为2,因为从根节点到到该节点的节点数为2,B的高度为3,而C的高度为2。

当然树的深度是4高度也是4。树的高度和深度是相等的。

我们可以递归的计算出左子树的高度和右子树的高度,然后取二者的最大值加1最为这棵二叉树的高度。 

Algorithm:

  height(T)
1. 如果树为空,则返回0
2. 否则
     (a) 通过递归地调用height(T.left)求出左子树的高度
     (b) 通过递归的调用height(T.right)求出右子树的高度
     (c) 利用如下公式求出二叉树的高度:
        height(T) = max(height(T.left),  height(T.right)) + 1
     (d) 返回height(T)
下图诠释了递归求解过程:

 height('1') = max(height('2'), height('3')) + 1
                               = 2 + 1
                                  /    \
                                /         \
                              /             \
                            /                 \
                          /                     \
               height('2') = 1                height('3') = 1
= max(height('4'), height('5')) + 1
= 1 + 1   = 2         
                   /    \
                 /        \
               /            \
             /                \
           /                    \
 height('4') = 1     height('5') = 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node{
    int h;
    char c;
    struct node *lt, *rt;
};
char pre[51];
char in[51];
struct node *create(int len, char pre[], char in[]){
    struct node *root;
    if(!len){
        root = NULL;
        return root;
    }
    root = (struct node *)malloc(sizeof(struct node));
    root -> c = pre[0];
    int i;
    for(i = 0; i < len; i++){
        if(pre[0] == in[i]){
            break;
        }
    }
    root -> lt = create(i, pre + 1, in);
    root -> rt = create(len - 1 - i, pre + 1 + i, in + 1 + i);
    return root;
}
int height(struct node *root){
    if(root -> lt == NULL && root -> rt == NULL){
        root -> h = 1;
    }
    else if(root -> lt != NULL && root -> rt == NULL){
        root -> h = height(root -> lt) + 1;
    }
    else if(root -> lt == NULL && root -> rt != NULL){
        root -> h  = height(root -> rt) + 1;
    }
    else if(root -> lt != NULL && root -> rt != NULL){
        if(height(root -> lt) > height(root -> rt)){
            return height(root -> lt) + 1;
        }
        else{
            return height(root -> rt) + 1;
        }
    }
    return root -> h;
}
int main(){
    int n;
    int th;
    while(~scanf("%d", &n)){
        scanf("%s", pre);
        scanf("%s", in);
        struct node *root;
        root = create(n, pre, in);
        th = height(root);
        printf("%d\n", th);
    }
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员豪仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值