算法:非完美二叉树的高度与直径

题目描述

记T为一棵二叉树,树中共有n个节点。

定义根节点的深度为0,其余节点的深度为其父节点的深度加1。T的高度定义为其叶节点深度的最大值。

定义树中任意两点a和b之间的距离为其间最短简单路径的长度。T的直径定义为T中所有点对间距离的最大值。

输入一棵二叉树T,请计算它的高度和直径。

输入

输入共三行。

第一行输入n的值,表示树中结点的总个数。

第二行为树的前序遍历表示,每个节点之间用空格隔开。

第三行为树的中序遍历表示,每个节点之间也用空格隔开。

输出

输出共两行。
第一行输出树的高度。
第二行输出树的直径。

样例输入

10
0 1 9 3 8 4 2 7 5 6
3 9 8 1 2 4 0 5 7 6

样例输出

3
5

提示

分治算法可以在O(n)的时间内完成相应的计算。

算法分析

涉及到树的相关操作,立马想到分治法,设树的直径为D,树的高度为H,那么该树的直径将可以通过递归式
D = m a x D 左子树, D 右子树, H 左子树 + H 右子树 + 2 D = max{D左子树,D右子树,H左子树+H右子树+2} D=maxD左子树,D右子树,H左子树+H右子树+2
求的。根据二叉树的前序序列和中序序列可以递归的求得树的高度,这里需仔细确定算法的basic problems,否则会发生树的高度的计算错误。该算法的时间复杂度为O(nlogn)。


#include<iostream>
 
 
using namespace std;
 
long tree_depth(long *A ,long *B , long start , long end,  long A_pos,long &distance);//用来计算树的高度
int main(void){
        long num = 0;
        cin >> num;
        if(num < 0){
                cout << 0 <<endl;
                cout << 0 << endl;
                return 0; 
        }       
        long *A = new long[num];//用来存储前序序列
        long *B = new long[num];//用来存储中序序列
        for(long i = 0; i < num; ++i){
                cin >> A[i];
        }       
        for(long i = 0; i < num; ++i){
                cin >> B[i];
        }       
        long distance  = 0;
        int tree_d = tree_depth(A, B, 0, num - 1, 0, distance);
         
        cout << tree_d <<endl;
        cout << distance  << endl;
        delete []B;
        B = NULL;
        delete []A;
        A = NULL;
         
}
 
long tree_depth(long * A, long * B, long start, long end, long A_pos, long & distance){
        if (start > end){
                distance = 0;
                return -1;
        }
        if (start == end){
                distance = 0;
                return 0;
        }
        long root_num = A_pos;//用来存储根在中序序列位置
        for(long j = start; j <= end; ++j){
                if(B[j] == A[A_pos]){
                        root_num =j;
                        break;
                }
        }
        long distance1 = distance, distance2 = distance;
        long left_high = tree_depth(A, B, start, root_num - 1, A_pos+1, distance1) ;
        long right_high = tree_depth(A, B, root_num + 1, end,  A_pos+1+(root_num - start), distance2);
        distance = distance1 > distance2 ? distance1 : distance2;
        if (right_high + left_high + 2> distance)
                distance = left_high + right_high + 2;
        return left_high > right_high?(left_high + 1): (right_high + 1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值