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

题目描述

记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 = max{D左子树,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);
}
阅读更多

没有更多推荐了,返回首页