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

来源:互联网 发布:java 上传大文件 编辑:程序博客网 时间:2024/06/04 14:27

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 ;}



0 0
原创粉丝点击