算法基础 - 树的最近公共祖先
2016-05-17 21:24
253 查看
最近公共祖先
二叉树的最近公共祖先
代码实现
普通树的最近公共祖先
代码实现
那么最近公共祖先就是公共路径(A, B)上深度最高的公共点。
这个是最简单的办法,下篇博客我会写LCA的在线和离线算法。
算法的复杂度会有一个质的变化。
二叉树的最近公共祖先
代码实现
普通树的最近公共祖先
代码实现
最近公共祖先
树的公共祖先很容易理解:就是到两个点的路径(A,B)上的公共点。那么最近公共祖先就是公共路径(A, B)上深度最高的公共点。
二叉树的最近公共祖先
二叉树的公共祖先很简单,就是在先序遍历也就是DFS过程中,记录当前的祖先,放到栈里,在遍历的过程中,不断对栈进行监控,当前遍历的最近公共祖先发生变化之后,对栈进行弹栈操作。代码实现
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ //上面是TreeNode的定义 vector<TreeNode*> treeStack; TreeNode* ancestor; int flag; //以上是全局变量 void findAncestor(TreeNode* node, TreeNode* p, TreeNode* q){ if(p == q){ ancestor = p; return; } if(node == NULL){ return; } if((node == p || node == q) && flag == 0){ flag = 1; treeStack.push_back(node); }else if((node == p || node == q) && flag == 1){ int length = treeStack.size(); ancestor = treeStack[length-1]; return; } if(flag == 0){ treeStack.push_back(node); } findAncestor(node->left, p, q); findAncestor(node->right, p, q); if(node == treeStack.back()){ treeStack.pop_back(); } }
普通树的最近公共祖先
普通树和二叉树在算法上并没有太多区别,只是在遍历的时候稍有不同,因为每个节点的孩子节点最多的时候不是两个了,所以用个for循环来进行遍历。代码实现:
// // main.cpp // HiHocoder // // Created by Alps on 16/5/9. // Copyright © 2016年 chen. All rights reserved. // #include<iostream> #include<cstring> #include<string> #include<unordered_map> #include<vector> using namespace std; vector<int> tree[100005]; unordered_map<int, int> nameSet; unordered_map<string, int> names; string strs[100005]; vector<int> path; int ance; int flag = 0; static int id = 0; int getId(string name){ if(names.count(name) == 0){ names[name] = id; strs[id] = name; id++; } return names[name]; } void findAnces(int node, int id_1, int id_2){ if (id_1 == id_2) { ance = id_1; flag = 2; return; } if(flag == 0){ path.push_back(node); } if(node == id_1){ flag += 1; } if(node == id_2){ flag += 1; } if(flag == 2){ ance = path.back(); return; } for(int i = 0; i < tree[node].size(); i++){ findAnces(tree[node][i], id_1, id_2); if (flag == 2) { return; } } if(node == path.back()){ path.pop_back(); } } int main(){ int M,N; cin>>M; string name_1, name_2; int id_1, id_2; for(int i = 0; i < M; i++){ cin>>name_1>>name_2; id_1 = getId(name_1); id_2 = getId(name_2); tree[id_1].push_back(id_2); nameSet[id_2] = id_1; if(nameSet.count(id_1) == 0){ nameSet[id_1] = id_1; } } int root = 0; while(nameSet[root] != root){ root = nameSet[root]; } cin>>N; for(int i = 0; i < N; i++){ cin>>name_1>>name_2; id_1 = getId(name_1); id_2 = getId(name_2); findAnces(root, id_1, id_2); cout<<strs[ance]<<endl; path.clear(); ance = 0; flag = 0; } return 0; }
这个是最简单的办法,下篇博客我会写LCA的在线和离线算法。
算法的复杂度会有一个质的变化。
相关文章推荐
- AVL树-自平衡二叉查找树(Java实现)
- C语言二叉树的非递归遍历实例分析
- 使用C语言构建基本的二叉树数据结构
- 一波二叉树遍历问题的C++解答实例分享
- 举例讲解C语言程序中对二叉树数据结构的各种遍历方式
- C++非递归队列实现二叉树的广度优先遍历
- PHP实现的线索二叉树及二叉树遍历方法详解
- C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法
- C#非递归先序遍历二叉树实例
- C++将二叉树转为双向链表及判断两个链表是否相交
- C++非递归建立二叉树实例
- C语言实现找出二叉树中某个值的所有路径的方法
- C++实现二叉树遍历序列的求解方法
- C语言实现二叉树遍历的迭代算法
- C++实现查找二叉树中和为某一值的所有路径的示例
- 用C语言判断一个二叉树是否为另一个的子结构
- C++实现二叉树非递归遍历方法实例总结
- C++二叉树结构的建立与基本操作
- 深入遍历二叉树的各种操作详解(非递归遍历)
- JavaScript数据结构和算法之二叉树详解