学习笔记41-寻找二叉树最近公共结点

来源:互联网 发布:mac关闭icloud drive 编辑:程序博客网 时间:2024/06/06 08:25

1. 有父指针

如果这棵二叉树有父指针,比较简单,时间复杂度是O(n)。
先把深度大的向上移,移到同一深度,再同时向上移动,直到两个结点相同就找到了公共父节点。

#include<stdio.h>struct node{    int data;    node *left;    node *right;    node *parent;    node():left(NULL),right(NULL),parent(NULL){};};int getDepth(node *n){    int count=0;    while(n)    {        ++count;        n=n->parent;    }    return count;}node *findAncestor(node *n1,node *n2){    int depth1=getDepth(n1);    int depth2=getDepth(n2);    while(depth1>depth2)    {        n1=n1->parent;        --depth1;    }    while(depth1<depth2)    {        n2=n2->parent;        --depth2;    }    while(n1!=n2)    {        n1=n1->parent;        n2=n2->parent;    }    return n1;}int main(){    node *a[11];    for(int i=0;i<11;i++)    {        a[i]=new node();        a[i]->data=i;    }    for(int i=0;i<5;++i)    {        a[i]->left=a[2*i+1];        a[2*i+1]->parent=a[i];        a[i]->right=a[2*i+2];        a[2*i+2]->parent=a[i];    }    node *ancestor=findAncestor(a[7],a[6]);    for(int i=0;i<11;i++)    {        printf(" %d",a[i]->data);    }    printf("\n");    printf("commonAncestor=%d\n",ancestor->data);    return 0;}

2. 没有父指针

没有父指针,只能从根结点开始向下遍历,如果根结点等于其中某一个结点,那么就找到了最近公共子结点。否则计算它的左子树和右子树中包含n1或n2的个数,如果左子树包含n1和n2,那么公共子结点一定在左子树,如果右子树包含n1和n2,那么公共子结点一定在右子树。如果左右子树各包含一个,那么公共子结点就是当前结点。
这个算法的时间复杂度,最坏是O(n^2),当树成为两个链表,时间复杂度就是O(n^2)。最好是O(log n),对一棵平衡二叉树,就是O(log n)。

#include<stdio.h>struct node{    int data;    node *left;    node *right;    node():left(NULL),right(NULL){};};int countMatch(node *current,node *n1,node *n2){    if(current==NULL)        return 0;    int count=countMatch(current->left,n1,n2)+countMatch(current->right,n1,n2);    if(current==n1||current==n2)        return 1+count;    return count;}node *findAncestor(node *root,node *n1,node *n2){    if(root==NULL)        return NULL;    if(root==n1||root==n2)        return root;    int count=countMatch(root->left,n1,n2);    if(count==1)        return root;    else if(count==2)        return findAncestor(root->left,n1,n2);    else        return findAncestor(root->right,n1,n2);}int main(){    node *a[11];    for(int i=0;i<11;i++)    {        a[i]=new node();        a[i]->data=i;    }    for(int i=0;i<5;i++)    {        a[i]->left=a[i*2+1];        a[i]->right=a[i*2+2];    }    node *ancestor=findAncestor(a[0],a[7],a[10]);    printf("ancestor=%d\n",ancestor->data);    return 0;}
原创粉丝点击