您的位置:首页 > 职场人生

微软面试100题系列---求二叉树中节点的最大距离

2016-09-02 16:30 525 查看

题目

如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义”距离”为两节点之间边的个数。写一个程序求一棵二叉树中相距最远的两个节点之间的距离;



实现

分析

计算一个二叉树的最大距离有两个情况:

情况A: 路径经过左子树的最深节点,通过根节点,再到右子树的最深节点。

情况B: 路径不穿过根节点,而是左子树或右子树的最大距离路径,取其大者。



只需要计算这两个情况的路径距离,并取其大者,就是该二叉树的最大距离。

方法1

思路:二叉树的操作一般都是递归实现的,此时也采用递归思想。

对于以node节点为根节点的树,首先求左子树距根的最大距离maxLeft;然后求右子树距根的最大距离maxRight;则以node为根的二叉树中节点最大距离为=maxLeft+maxRight;

对于每个节点,都记录了左子树到该节点的最大距离,右子树到该节点的最大距离;

代码:

public class Num11 {

public static int maxLen=0;
public static void main(String[] args) {
Node root_1=createTree_1();
Node root_2=createTree_2();
/*
FindMaxDistance(root_1);
System.out.println(maxLen);

maxLen=0;*/
FindMaxDistance(root_2);
System.out.println(maxLen);
}

public static Node createTree_1(){
Node root=new Node(1);
Node node=new Node(2);
root.left=node;
node=new Node(3);
root.right=node;

node=new Node(4);
root.left.left=node;
root.left.right=new Node(5);

root.right.left=new Node(6);
root.right.right=new Node(7);

root.left.left.left=new Node(8);
root.right.right.left=new Node(9);

return root;
}

public static Node createTree_2(){
Node root=new Node(1);

Node node=new Node(2);
root.left=node;

node=new Node(3);
root.left.left=node;
root.left.right=new Node(5);

root.left.left.left=new Node(4);
root.left.right.right=new Node(6);

return root;
}

public static void FindMaxDistance(Node root){
if(root==null){
return;
}
if(root.left==null){
root.leftMaxDistance=0;
}
if(root.right==null){
root.rightMaxDistance=0;
}
if(root.left!=null){
FindMaxDistance(root.left);
}
if(root.right!=null){
FindMaxDistance(root.right);
}
if(root.left!=null){
root.leftMaxDistance=max(root.left.leftMaxDistance,root.left.rightMaxDistance)+1;
}
if(root.right!=null){
root.rightMaxDistance=max(root.right.leftMaxDistance,root.right.rightMaxDistance)+1;
}
if(root.leftMaxDistance+root.rightMaxDistance>maxLen){
maxLen=root.leftMaxDistance+root.rightMaxDistance;
}
}

private static int max(int a, int b) {
return a>b?a:b;
}

}

class Node{
int value;
Node left;
Node right;
int leftMaxDistance;
int rightMaxDistance;

public Node(int value){
this.value=value;
this.left=null;
this.right=null;
}
}


方法2

这个问题的核心是,情况A 及 B 需要不同的信息: A 需要子树的最大深度,B 需要子树的最大距离。只要函数能在一个节点同时计算及传回这两个信息(将这2类消息封装到一个类中);

public class Num11_2 {

public static void main(String[] args) {
Node_2 root_1=createTree_1();
Result res_1=FindMaxDistance(root_1);
System.out.println(res_1.maxDistance+"   "+res_1.maxDepth);

Node_2 root_2=createTree_2();
Result res_2=FindMaxDistance(root_2);
System.out.println(res_2.maxDistance+"   "+res_2.maxDepth);
}

public static Node_2 createTree_1(){
Node_2 root=new Node_2(1);
Node_2 node=new Node_2(2);
root.left=node;
node=new Node_2(3);
root.right=node;

node=new Node_2(4);
root.left.left=node;
root.left.right=new Node_2(5);

root.right.left=new Node_2(6);
root.right.right=new Node_2(7);

root.left.left.left=new Node_2(8);
root.right.right.left=new Node_2(9);

return root;
}

public static Node_2 createTree_2(){
Node_2 root=new Node_2(1);

Node_2 node=new Node_2(2);
root.left=node;

node=new Node_2(3);
root.left.left=node;
root.left.right=new Node_2(5);

root.left.left.left=new Node_2(4);
root.left.right.right=new Node_2(6);

return root;
}

public static Result FindMaxDistance(Node_2 root){
if(root==null){
return new Result(-1,0);
}

Result lhs=FindMaxDistance(root.left);
Result rhs=FindMaxDistance(root.right);

Result res=new Result();
res.maxDepth=max(lhs.maxDepth+1,rhs.maxDepth+1);
res.maxDistance=max(max(lhs.maxDistance,rhs.maxDistance),lhs.maxDepth+rhs.maxDepth+2);

return res;
}

private static int max(int i, int j) {
return i>j?i:j;
}

}
class Node_2{
int value;
Node_2 left;
Node_2 right;

public Node_2(int value){
this.value=value;
this.left=null;
this.right=null;
}
}

class Result{
int maxDepth;
int maxDistance;

public Result(){

}

public Result(int maxDepth,int maxDistance){
this.maxDepth=maxDepth;
this.maxDistance=maxDistance;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: