计算二叉树中两个节点的距离

问题

对于普通的二叉树,如何找到两个给定节点之家的距离?距离是指连接两个节点需要的最小的边的条数。

例如下面的二叉树:

dist

 

这个问题很全面的考察了二叉树相关的知识,建议大家先尝试自己解决~

分析

假设给定的节点为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) 

 这个公式已经含盖了上面的两种情况。先找出lca,再求root节点到某个节点的距离就比较简单了。

 

以下是C++代码:

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 typedef struct node{
 7     int val;
 8     node *lchild;
 9     node *rchild;
10     node(int x) : val(x), lchild(NULL), rchild(NULL) {}
11 }Node;
12 
13 //计算节点值为n到根节点的距离,-1表示没有在root树下找到
14 int findlevel(Node *root, int n){
15     if(root == NULL)
16         return -1;
17     if(root->val == n)
18         return 0;
19     //先在左子树中查找
20     int level = findlevel(root->lchild, n);
21     //左子树中没有找到则到右子树中查找
22     if(level == -1)
23         level = findlevel(root->rchild, n);
24     if(level != -1)
25         return level+1;
26     return -1;
27 }
28 
29 //找两个节点的最近公共祖先
30 Node *findLCA(Node *root, int n1, int n2){
31     if(root == NULL)
32         return NULL;
33     //找到两个节点中的一个就返回
34     if((root->val == n1) || (root->val == n2))
35         return root;
36     //分别在左右子树查找两个节点
37     Node *l = findLCA(root->lchild, n1, n2);
38     Node *r = findLCA(root->rchild, n1, n2);
39     if((l != NULL) && (r != NULL))
40         //此时说明,两个节点分别在左右子树中,当前节点就是LCA
41         return root;
42     return ((l == NULL) ? r : l);
43 
44 }
45 
46 //计算两个节点的距离
47 int distance(Node *root, int n1, int n2){
48     Node *lca = findLCA(root, n1, n2);
49     int dis_lca = findlevel(root, lca->val);
50     int dis_n1 = findlevel(root, n1);
51     int dis_n2 = findlevel(root, n2);
52     //cout << dis_lca << dis_n1 << dis_n2 << endl;
53     int ans = dis_n1 + dis_n2 - 2 * dis_lca;
54     return ans;
55 }
56 
57 //前序遍历
58 void travel(Node *root){
59     if(root == NULL)
60         return;
61     cout << root->val;
62     travel(root->lchild);
63     travel(root->rchild);
64 }
65 
66 int main(){
67     Node *root = new Node(1);
68     root->lchild = new Node(2);
69     root->rchild = new Node(3);
70     root->lchild->lchild = new Node(4);
71     root->lchild->rchild = new Node(5);
72     root->rchild->lchild = new Node(6);
73     root->rchild->rchild = new Node(7);
74     root->rchild->lchild->rchild = new Node(8);
75     travel(root);
76     cout << endl;
77     cout << "dis(4,5) = " << distance(root, 4, 5) << endl;
78     cout << "dis(4,6) = " << distance(root, 4, 6) << endl;
79     cout << "dis(3,4) = " << distance(root, 3, 4) << endl;
80     cout << "dis(2,4) = " << distance(root, 2, 4) << endl;
81     cout << "dis(8,5) = " << distance(root, 8, 5) << endl;
82     cout << "dis(1,4) = " << distance(root, 1, 4) << endl;
83     system("pause");
84     return 0;
85 }

结果:

posted @ 2016-08-06 16:49  琴影  阅读(1799)  评论(0编辑  收藏  举报