寻找二叉树两个节点的最低公共祖先
2016-04-08 10:21
543 查看
方法
下面是一个简单的复杂度为 O(n) 的算法,解决LCA问题1) 找到从根到n1的路径,并存储在一个向量或数组中。
2)找到从根到n2的路径,并存储在一个向量或数组中。
3) 遍历这两条路径,直到遇到一个不同的节点,则前面的那个即为最低公共祖先.
下面的C++的程序实现
view source
01 | // O(n) 解决 LCA |
02 | #include <iostream> |
03 | #include <vector> |
04 | using namespace std; |
05 |
06 | //二叉树节点 |
07 | struct Node |
08 | { |
09 | int key; |
10 | struct Node *left, *right; |
11 | }; |
12 | //公用函数,生成一个节点 |
13 | Node * newNode( int k) |
14 | { |
15 | Node *temp = new Node; |
16 | temp->key = k; |
17 | temp->left = temp->right = NULL; |
18 | return temp; |
19 | } |
20 | //找到从root到 节点值为key的路径,存储在path中。没有的话返回-1 |
21 | bool findpath(Node * root,vector< int > &path, int key){ |
22 | if (root == NULL) return false ; |
23 | path.push_back(root->key); |
24 | if (root->key == key) return true ; |
25 | //左子树或右子树 是否找到,找到的话当前节点就在路径中了 |
26 | bool find = ( findpath(root->left, path, key) || findpath(root->right,path ,key) ); |
27 | if (find) return true ; |
28 | //该节点下未找到就弹出 |
29 | path.pop_back(); |
30 | return false ; |
31 | } |
32 |
33 | int findLCA(Node * root, int key1, int key2){ |
34 | vector< int > path1,path2; |
35 | bool find1 = findpath(root, path1, key1); |
36 | bool find2 = findpath(root, path2, key2); |
37 | if (find1 && find2){ |
38 | int ans ; |
39 | for ( int i=0; i<path1.size(); i++){ |
40 | if (path1[i] != path2[i]){ |
41 | break ; |
42 | } else |
43 | ans = path1[i]; |
44 | } |
45 | return ans; |
46 | } |
47 | return -1; |
48 | } |
49 |
50 | // Driver program to test above functions |
51 | int main() |
52 | { |
53 | // 按照上面的图来创创建树 |
54 | Node * root = newNode(1); |
55 | root->left = newNode(2); |
56 | root->right = newNode(3); |
57 | root->left->left = newNode(4); |
58 | root->left->right = newNode(5); |
59 | root->right->left = newNode(6); |
60 | root->right->right = newNode(7); |
61 | cout << "LCA(4, 5) = " << findLCA(root, 4, 5); |
62 | cout << "\nLCA(4, 6) = " << findLCA(root, 4, 6); |
63 | cout << "\nLCA(3, 4) = " << findLCA(root, 3, 4); |
64 | cout << "\nLCA(2, 4) = " << findLCA(root, 2, 4); |
65 | return 0; |
66 | } |
相关文章推荐
- scanf&printf VS cin&cout
- HDOJ 1330 Deck(叠木块-物理题啊!贪心算法用到了一点)
- 报错:java.util.Map is an interface, and JAXB can't handle interfaces.
- HDOJ 1330 Deck(叠木块-物理题啊!贪心算法用到了一点)
- QQ会员活动运营平台架构设计实践——高效自动化运营
- iOS开发~设置导航条颜色,导航条标题颜色、字体大小以及导航条返回按钮及其他Item颜色
- Android - 图像
- java之动态代理
- 华为笔试题 明明的随机数
- android AIDL进程间通信
- HashMap的工作原理
- Java执行顺序
- sqlite3 api sqlite3_busy_timeout 与 sqlite3_busy_handler 的使用与区别
- Linux ifstat --网络接口检测工具
- Linux ifconfig --网络配置命令
- SparkR去数据子集错误:object of type 'S4' is not subsettable
- 网络字节序与主机字节序
- 从此不求人:自主研发一套PHP前端开发框架(16)
- 正则表达式的顺序优先级
- java反射机制