二叉树中俩点距离就是俩个点的边的条数。
分析
假设给定的节点为node1, node2,可以分为下面两种情况:
1) node1是node2的祖先节点或孩子节点,可以理解为两个节点在一条线上。 例如:Dist(2,4), Dist(6,1)
2) node1 和 node2 没有直接或间接的父子关系。 例如,Dist(4,3), 他们需要一个共同的祖先节点1 连接起来。
这里涉及两个节点的最低公共祖先(LCA)问题,可以参考我的上一篇博客。
通过观察可以总结出下面的公式, lca是两个节点的最低公共祖先节点:
Dist(n1, n2) = Dist(root, n1) + Dist(root, n2) - 2*Dist(root, lca)
public class App
{
static class Node {
Node left;
Node right;
int key;
Node(int key) {
this.key = key;
this.left = null;
this.right = null;
}
}
static int findLevel(Node root, int key) {
if(root == null) {
return -1;
}
if(root.key == key) {
return 0;
}
int level = findLevel(root.left, key);
if(level == -1) {
level = findLevel(root.right, key);
}
if(level!=-1) {
return level+1;
}
return -1;
}
static Node findLCA(Node root, int n1, int n2) {
if(root == null) {
return null;
}
if(root.key == n1 || root.key == n2) {
return root;
}
Node left = findLCA(root.left, n1, n2);
Node right = findLCA(root.right, n1, n2);
if(left!=null && right!=null) {
return root;
}
else {
return left!=null?left:right;
}
}
static int disBetweenNodes(Node root, int node1, int node2) {
//公共最低祖先
Node lca = findLCA(root, node1, node2);
int level_lca = findLevel(root, lca.key);
int dis1 = findLevel(root, node1);
int dis2 = findLevel(root, node2);
return dis1 + dis2 - 2*level_lca;
}
public static void main( String[] args )
{
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
System.out.println(disBetweenNodes(root, 3, 4));
}
}
结果为3,具体过程请自行研究。