二叉树中两个节点的最低公共祖先
引用编程之美,引用网址: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 }