二叉树中两个节点的最低公共祖先

引用编程之美,引用网址:http://zhedahht.blog.163.com/blog/static/25411174201081263815813/

情况一:二叉树为搜索二叉树

情况二:如果存在指向父节点的指针,则转换为求两个链表的第一个公共节点

情况三:为一般的二叉树

针对情况三:

 1 //判断一棵树是否含有某个节点
 2 //利用递归方式的前序优先遍历,时间复杂度O(n)
 3 bool isHave(treeNode* root, treeNode* pNode){
 4     if(root==NULL)
 5         return false;
 6     if(root==pNode)
 7         return true;
 8     //判断左子树是否含有该节点
 9     bool found=false;
10     if(root->lChild!=NULL)
11         found=isHave(root->lChild,pNode);
12     //如果左子树不含有,则判断右子树
13     if(!found && root->rChild!=NULL)
14         found=isHave(root->rChild,pNode);
15     return found;
16 }

 

 1 //求最低公共祖先
 2 //从根节点开始,每个节点调用isHave,时间复杂度O(n^2)
 3 treeNode* lastComParent(treeNode* root,treeNode* pNode1,treeNode* pNode2){
 4     if(root==NULL || pNode1==NULL || pNode2==NULL)
 5         return NULL;
 6     if(root==pNode1 || root==pNode2)
 7         return NULL;
 8     //两个节点在root的左子树中的分布情况
 9     bool leftHasNode1=false;
10     bool leftHasNode2=false;
11     if(root->lChild!=NULL){
12         leftHasNode1=isHave(root->lChild,pNode1);
13         leftHasNode2=isHave(root->lChild,pNode2);
14     }
15     //两个节点在root的右子树中的分布情况
16     bool rightHasNode1=false;
17     bool rightHasNode2=false;
18     if(root->rChild!=NULL){
19         if(!leftHasNode1)
20             rightHasNode1=isHave(root->rChild,pNode1);
21         if(!leftHasNode2)
22             rightHasNode2=isHave(root->rChild,pNode2);
23     }
24     //分三种情况
25     //当两个节点都在左子树查找成功时(leftHasNode1和leftHasNode2都为true),
26     //则root是公共祖先,但不一定是最低的
27     if(leftHasNode1 && leftHasNode2){
28         //判断root是否为最低的公共祖先
29         if(root->lChild==pNode1 || root->rChild==pNode2)
30             return root;
31         else return lastComParent(root->lChild,pNode1,pNode2);
32     }
33     //当两个节点都在右子树查找成功时
34     else if(rightHasNode1 && rightHasNode2){
35         if(root->rChild==pNode1 || root->rChild==pNode2)
36             return root;
37         else return lastComParent(root->rChild,pNode1,pNode2);
38     }
39     //当两个节点分别位于左右子树时
40     else if((leftHasNode1&&rightHasNode2) || (leftHasNode2&&rightHasNode1))
41         return root;
42     else return NULL;
43 }

 

posted @ 2014-09-18 09:44  liuzhiminxd  阅读(284)  评论(0编辑  收藏  举报