您的位置:首页 > 其它

LCA(Least Common Ancestors)最近公共祖先

2016-06-06 16:37 477 查看
LCA(Least Common Ancestors),即最近公共祖先,是指这样一个问题:在有根树中,找出某两个结点u和v最近的公共祖先(另一种说法,离树根最远的公共祖先)。

对于该问题,最容易想到的算法是分别从节点u和v回溯到根节点,获取u和v到根节点的路径P1,P2,其中P1和P2可以看成两条单链表,这就转换成常见的一道面试题:【判断两个单链表是否相交,如果相交,给出相交的第一个点。】。该算法总的复杂度是O(n)(其中n是树节点个数)。



构建上面这个树,求节点F和节点H的最近公共祖先

<pre name="code" class="cpp">#include <stdio.h>
#include <stdlib.h>

struct TreeNode {
char element;
struct TreeNode **child;
unsigned int child_num;
};
typedef struct TreeNode * Tree_t;
struct PathNode {
char element;
struct PathNode * next;
};
typedef struct PathNode * Path_list;
Tree_t g_tree;

Path_list dsf(Tree_t tree,Path_list path,char element) {
unsigned int i;
Tree_t tmp;
Path_list tmp_path;
if(NULL == tree)
return;
//printf("Element is %d\n",tree->element);
tmp_path = (Path_list)malloc(sizeof(struct PathNode));
if(tmp_path == NULL) {
printf("malloc path list error\n");
exit(-1);
}
tmp_path->next = NULL;
tmp_path->element = tree->element;
if(path != NULL) {
path->next = tmp_path;
}else {
path = tmp_path;
}
if(tree->element == element) {
return path;
}
for(i = 0; i < tree->child_num;i++) {
tmp = tree->child[i];
if(NULL != dsf(tmp,tmp_path,element))
return tmp_path;
free(tmp_path->next);
tmp_path->next = NULL;
}
return NULL;
}

void main(int argc, char *argv[])
{
unsigned int i;
Tree_t tree;
Tree_t next_tree;
Path_list path_a,path_b;
char common_node = 255;

g_tree = (Tree_t)malloc(sizeof(struct TreeNode));
if(g_tree == NULL) {
printf("g_tree malloc error\n");
return;
}
g_tree->element = 'A';
g_tree->child_num = 2;

g_tree->child = (Tree_t *)malloc(sizeof(Tree_t));
for(i = 0; i < 2; i++) {
g_tree->child[i] = (Tree_t)malloc(sizeof(struct TreeNode));
if(g_tree->child[i] == NULL) {
printf("malloc g_tree child error\n");
exit(-1);
}
}
g_tree->child[0]->element = 'B';
g_tree->child[0]->child_num = 2;
g_tree->child[1]->element = 'C';
g_tree->child[1]->child_num = 0;
g_tree->child[1]->child = NULL;

tree = g_tree->child[0];
tree->child = (Tree_t *)malloc(sizeof(Tree_t)*2);
for(i = 0; i < 2;i++) {
tree->child[i] = (Tree_t)malloc(sizeof(struct TreeNode));
if(tree->child[i] == NULL) {
printf("malloc tree child error\n");
exit(-1);
}
}
tree->child[0]->element = 'D';
tree->child[0]->child_num = 2;

tree->child[1]->element = 'E';
tree->child[1]->child_num = 3;

next_tree = tree->child[0];
next_tree->child = (Tree_t *)malloc(sizeof(Tree_t)*2);
for(i = 0; i < 2;i++) {
next_tree->child[i] = (Tree_t)malloc(sizeof(struct TreeNode));
if(next_tree->child[i] == NULL) {
printf("malloc next tree child error\n");
exit(-1);
}
}
next_tree->child[0]->element = 'F';
next_tree->child[0]->child_num = 0;
next_tree->child[1]->element = 'G';
next_tree->child[1]->child_num = 0;

next_tree = tree->child[1];
next_tree->child = (Tree_t *)malloc(sizeof(Tree_t)*3);
for(i = 0; i < 3;i++) {
next_tree->child[i] = (Tree_t)malloc(sizeof(struct TreeNode));
if(next_tree->child[i] == NULL) {
printf("malloc next tree child error\n");
exit(-1);
}
}

next_tree->child[0]->element = 'H';
next_tree->child[0]->child_num = 0;
next_tree->child[1]->element = 'I';
next_tree->child[1]->child_num = 0;
next_tree->child[2]->element = 'J';
next_tree->child[2]->child_num = 0;

path_a = NULL;
path_b = NULL;

path_a = dsf(g_tree,path_a,'F');
path_b = dsf(g_tree,path_b,'H');

while(path_a && path_b && (path_a->element == path_b->element)) {
common_node = path_a->element;
path_a = path_a->next;
path_b = path_b->next;
}

if(common_node != 255) {
printf("find LCA node %c\n",common_node);
}else {
printf("no LCA node\n");
}
return ;
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LCA 最近公共节点