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

13人阅读 评论(0) 收藏 举报
分类:

题目描述

记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);
}
查看评论

数据结构——二叉树的直径

原文地址:Diameter of a Binary Tree树的直径(有时也称作宽度),指的是树中的两个叶子节点之间最长路径的节点的数目,下面的图显示了两个树的直径都是9,形成最长路径的两个端点的叶子...
  • sinat_36246371
  • sinat_36246371
  • 2016-11-26 15:33:58
  • 1206

[各种面试题] 非二叉树的最大路径和

给定一棵树的根结点,树中每个结点都包含一个整数值val。我们知道树中任意2个结点之间都存在唯一的一条路径,路径值为路径上所有结点值之和。请计算最大的路径值(允许路径为空)。 样例: ...
  • a83610312
  • a83610312
  • 2013-09-17 21:01:41
  • 1595

数据结构中求二叉树的高度和宽度C++代码

  • 2010年01月05日 10:36
  • 3KB
  • 下载

树直径、二叉树直径 Tree diameter (Longest path in an undirected tree)

树直径问题其实就好像在一个无向无环图中找一条最长的路径,核心思想其实也很简单: 首先从任意一个节点开始BFS找距离最远能到达的点(以该点作为根节点树的最深层),假设到达点为V,再以V为根节点找最远能...
  • Mrx_Nh
  • Mrx_Nh
  • 2017-05-17 13:59:46
  • 465

求树的“直径”以及所想到的

算法导论22.2-7题:树T=(V,E)的直径(diameter)定义为max(u,v),亦即,树的直径是树中所有最短路径长度中的最大值。试写出计算树的直径的有效算法,并分析算法的运行时间。 如果这...
  • gzxcyy
  • gzxcyy
  • 2013-11-05 14:59:07
  • 1578

经典算法学习——求二叉树的高度

二叉树是一种递归定义的数据结构,我们对它做的几乎所有的操作都是递归的。求树的高度也是如此。分别求左右子树的高度,然后取较长的子树作为高度。代码上传至 https://github.com/chenyu...
  • CHENYUFENG1991
  • CHENYUFENG1991
  • 2016-10-02 21:10:39
  • 6244

网易面试题之求出树的直径

给定一颗二叉树,求出树中的任意两个节点之间的最大距离,即树的直径。         从这个题目可以看到,树中任意两个节点的最大距离,显然应该是不同叶子间的最大距离。我们可以根据树的节点分布情况分情况...
  • dqjyong
  • dqjyong
  • 2012-08-02 23:00:59
  • 4147

计算二叉树的高度的递归和非递归实现

1.递归方法 int FindTreeDeep(BinTree BT){ int deep=0; if(BT){ int lchilddeep=FindTr...
  • a1231988
  • a1231988
  • 2014-06-29 15:38:44
  • 2477

两次BFS求树的直径(算法导论22.2-7)

以任意点w开始,先做一次BFS,找到最远的点v,然后再以此点v进行一次BFS,找到最远的点为u,u到v就是树的直径。   此问题的关键不是在编程,而是要证明,网上也找了很多资料,没有看到证明,以下是个...
  • wdq347
  • wdq347
  • 2013-07-15 09:08:32
  • 3464

二叉链表作存储结构,设计求二叉树高度的算法

  • 2011年02月17日 13:19
  • 1KB
  • 下载
    个人资料
    等级:
    访问量: 204
    积分: 60
    排名: 156万+
    文章分类
    文章存档