typedef struct Node{                        
    struct Node *lchild;                    
    char data;                
    struct Node *rchild;
}BTNode;  
//求二叉搜索树的公共祖先
1.二叉搜索树具有一个很好的特点。以当前结点为根节点的左边结点的值都是小于根节点的值,右边结点的值都大于根节点的值。 
2.根据这个特点,如果给的两个节点的值都小于根节点,那么它们的最低公共祖先就一定在它左子树。 
3.如果给的两个节点的值都大于根节点,那么它们的最低公共祖先就一定在它右子树。 
4.如果一个结点的值大于根节点的值,一个结点的值小于根节点的值,那么这个根节点就是它的最低公共祖先。
BTNode* getLowestCommonParent(BTNode* root, BTNode* node1, BTNode* node2)
{
    if (root == NULL || node1 == NULL || node2 == NULL)
        return NULL;

    if ((node1->data < root->data) && (node2->data< root->data))
    {
        return getLowestCommenParent(root->lchild, node1, node2);
    }else if ((node1->data > root->data) && (node2->data > root->data)){
        return getLowestCommenParent_R(root->rchild, node1, node2);
    }else{
        return root;
    }        
}

 

 

//求普通二叉树的最低公共祖先
二叉树问题一般都可以用递归去解决,要想通过递归实现,就需要先确定临界条件。那么什么是临界条件呢?换句话说,临界条件就是递归中能够直接返回的特殊情况。
(1)第一点则是最常见的“判空”,判断根结点是否是空节点,如果是,那么肯定就可以马上返回了;
(2)再来考虑题意,在以root为根结点的树中找到p结点和q结点的最近公共祖先,那么特殊情况是什么呢?很显然,特殊情况就是根结点就等于q结点或p结点的情况,想一下,如果根结点为二者之一,那么根结点就必定是最近公共祖先了,这时直接返回root即可。
由此看来,这道题共有三种特殊情况即root == q 、root == p以及root==null,均直接返回root即可。
根据临界条件,此题已经被简化为查找以root为根结点的树上是否有p结点或者q结点,如果有就返回p结点或q结点,否则返回null。
这样一来就很简单了,从左右子树分别进行递归,即查找左右子树上是否有p结点或者q结点,就一共有4种情况:
第一种:左右子树均没有找到p或者q结点;(虽然题上说p和q结点必定都存在,但递归的时候必须考虑所有情况,因为题目是针对整棵树,而递归会到局部,局部不一定都满足整体条件)
第二种:左子树上能找到,但右子树上找不到,此时就应当直接返回左子树的查找结果;
第三种:右子树上能找到,但左子树上找不到,此时就应当直接返回右子树的查找结果;
第四种:左右子树上均能找到,说明此时的p和q结点分居root两侧,此时就应当直接返回root结点了。

BTNode* getLowestCommonParent(BTNode* root, BTNode* node1, BTNode* node2)
{
    if (root == NULL || node1 == root || node2 == root)
        return root;
    BTNode* left =getLowestCommonParent(root->lchild, node1,node2);
    BTNode* right =  getLowestCommonParent(root->rchild, node1,node2);

    if(left==NULL && right==NULL){
          return NULL;
    } else if(left!=NULL && right==NULL){
          return left;
    } else if(right!=NULL&&left==NULL){
          return right;
    } else{
          return root;
    }        
}

 

二叉树任意两节点之间的最短路径长度
1.求出两个节点的最近公共祖先lowestCommonRoot
2.利用深度搜索(先序)分别求出node1和node2到root的路径
3.对两个路径长度求和即得所求

bool getPath(BTNode* root,BTNode* target,Queue<TreeNode*> queue){
    if (root==target){
        return true;
    }     
    in(queue,root);
    bool found=false;
    if (root->lchild!=NULL)
        found=getPath(root->lchild,target,queue);
    if (!found && root->rchild!=NULL)
        found=getPath(root->rchild,target,queue);
    if (!found)
        reverseOut(queue);
    return found; 
}


BTNode* lowestCommonRoot = getLowestCommonParent(root,node1,node2);
getPath(lowestCommonRoot,node1,queue1);
getPath(lowestCommonRoot,node2,queue2);
queue1->length+queue2->length

 

相关文章: