声明:题目来自: http://blog.csdn.net/v_JULY_v/archive/2010/11/17/6015165.aspx JULY整理了100道微软等公司的面试题目,我想先不看答案:http://blog.csdn.net/v_JULY_v/archive/2011/01/10/6126406.aspx 自己先做一遍。
题目:
/*
第11题
求二叉树中节点的最大距离...
如果我们把二叉树看成一个图,
父子节点之间的连线看成是双向的,
我们姑且定义"距离"为两节点之间边的个数。
写一个程序,
求一棵二叉树中相距最远的两个节点之间的距离。
*/
思路:
看到这个题目,我第一个想到的就是BFS,Breath-First-Search, 原因是我在看“算法导论”的时候见到过这个题目,算法导论第二版,第22章"Elementary Graph Algorithms" 第二节 "BFS", 的习题22.2-7 --> the diameter is the largest of all shortest path distances in the tree. Given an algorithm to compute the diameter of a tree and analyze the running time of your algorithm.
我的第一反应是:找到树的最深的叶子节点,和次深的叶子节点,这两个节点到根节点的和就是直径, 马上就否决了:
0
/
1
/ /
2 3
/
4
看上面这棵树, 4和3是最深的两个叶子节点,他们的最短距离是3,根本就不经过根节点。那是不是最深的两个叶子节点到他们的最近的共同祖先的距离和就是直径呢?也不是的,就上面的图来说,如果2有右儿子5,那么最深的两个节点 4,5到他们最近的共同祖先2的和是2,而这棵树的直径确是3.
回到BFS的思路上来,我的想法是:如果我能找到最深的叶子节点,那是不是从那个叶子节点(假设是U)出发做一遍BFS,树的直径就是U到距离U最远的节点V之间的距离?
这里的关键是证明:树的最深的叶子节点U一定在直径上!
证明: 有两种可能
a) 如果直径路径经过根节点: 反证法,如果U不在直径上,那存在另外一个X在直径上,因为直径经过根节点R,那么直径路径Distance(X->V) = Distance(X->R) + Distance (R->V); 这里,X->V 表示从X走到V,Distance(X->V)表示X走到V的最短距离。因为 U比X深,所以 Distance(U->R) > Distance(X->R), 那我们用U->R 替换 X->R的话就得到一条比直径更长的路径,于直径的定