(MS面试题) 公共最近父节点(LCA)的O(n)算法
这个题目出现在MS公司的一次面试题当中。公共最近父节点,也叫公共最近祖先(Least Common Ancestors),就是寻找二叉书中,两个结点最近的祖先结点。
在网上查找资料的时候,看到有Tarjan离线算法,过程比较复杂,我自己写了一个复杂度O(n)的算法,思路比较清晰,算法的长度也只有10行左右。经过简单的测试,可以找到正确结果。欢迎大家指正。
整个过程是一次后续遍历二叉树的过程,在遍历的过程中,会得到所有公共父结点,代码中采用了flag表示已经找出了最近的父节点,从而取消之后得到的更远的父节点赋值。从而返回最近的父节点。该方法可以在小范围的修改上,编程寻找多个结点的最近父节点算法。
LCA函数的源代码如下:
- int search_lcn(tree root, tree_node node1, tree_node node2, int *flag, tree_node *pres)
- {
- if (root)
- {
- int res = (root->id == node1.id || root->id == node2.id) + search_lcn(root->left, node1, node2, flag, pres) + search_lcn(root->right, node1, node2, flag, pres);
- if (res == 2 && *flag == 0)
- {
- pres->id = root->id;
- *flag = 1;
- }
- return res;
- }
- return 0;
- }
int search_lcn(tree root, tree_node node1, tree_node node2, int *flag, tree_node *pres)
{
if (root)
{
int res = (root->id == node1.id || root->id == node2.id) + search_lcn(root->left, node1, node2, flag, pres) + search_lcn(root->right, node1, node2, flag, pres);
if (res == 2 && *flag == 0)
{
pres->id = root->id;
*flag = 1;
}
return res;
}
return 0;
}
数的结点采用id来表示。构建二叉树的代码,如下:
- typedefstruct tree_node
- {
- int id;
- struct tree_node *left;
- struct tree_node *right;
- }tree_node, *tree;
- void build_bitree(tree *proot) //proot 的类型为 tree_node **
- {
- int val;
- scanf("%d", &val);
- if (val == -1)
- {
- *proot = NULL;
- }
- else
- {
- *proot = (tree_node *) malloc(sizeof (tree_node));
- (*proot)->id = val;
- build_bitree(&((*proot)->left));
- build_bitree(&((*proot)->right));
- }
- }
typedef struct tree_node
{
int id;
struct tree_node *left;
struct tree_node *right;
}tree_node, *tree;
void build_bitree(tree *proot) //proot 的类型为 tree_node **
{
int val;
scanf("%d", &val);
if (val == -1)
{
*proot = NULL;
}
else
{
*proot = (tree_node *) malloc(sizeof (tree_node));
(*proot)->id = val;
build_bitree(&((*proot)->left));
build_bitree(&((*proot)->right));
}
}
测试的代码,main函数如下面所示:
- int main()
- {
- tree root;
- build_bitree(&root); //proot 的类型为 tree_node **
- tree_node node1 = {3, NULL, NULL};
- tree_node node2 = {6, NULL, NULL};
- int flag = 0;
- tree_node resnode = {0, NULL, NULL};
- search_lcn(root, node1, node2, &flag, &resnode);
- printf("resnode->id = %d\n", resnode.id);
- return 0;
- }
int main()
{
tree root;
build_bitree(&root); //proot 的类型为 tree_node **
tree_node node1 = {3, NULL, NULL};
tree_node node2 = {6, NULL, NULL};
int flag = 0;
tree_node resnode = {0, NULL, NULL};
search_lcn(root, node1, node2, &flag, &resnode);
printf("resnode->id = %d\n", resnode.id);
return 0;
}
聚拓互联(http://www.ejutuo.com).Net平台至强虚拟主机供应商,是领先的互联网基础应用服务提供商,主要面向全球客户提供域名注册、国内、香港/美国虚拟主机、企业邮箱、智能建站、虚拟服务器(VPS)、服务器租用、服务器托管等丰富的网络产品服务。
聚拓互联的快速发展与其企业文化密不可分,易网人秉持“团结互助、敬业负责、恪守信誉、积极进取、勇于创新”的企业文化,汇聚了行业内的大量专业人士,拥有多位国内顶尖的linux/freeBSD/unix经验的系统工程师、微软认证工程师和网络安全技术人才。核心团队均为该行业从业多年的专业人士,拥有丰富行业经验和较高威望,并不断改革创新,以满足客户多元化需求为己任,不断进取。 同时,易网坚守 “专业品质、服务为本、诚信经营、恪守信誉”的核心价值观,为客户提供多样、安全、稳定、放心的产品。
浙公网安备 33010602011771号