共有三种情况:
1、两个节点如果一个在左子树,一个在右子树的话,则根节点就是它们的最低父节点
2、两个节点全在左子树中
3、两个节点全在右子树中
#include
#include
#include
#include
using namespace std;
typedef struct treeNode{
int data;
struct treeNode *pLeft;
struct treeNode *pRight;
}treeNode;
//判断节点是否存在
bool hasNode(treeNode *pRoot, int val){
if(pRoot == NULL){
return false;
}
if(pRoot->data == val){
return true;
}
bool found = false;
//节点是否在左子树中
found = hasNode(pRoot->pLeft, val);
if(!found){
found = hasNode(pRoot->pRight, val);
}
return found;
}
treeNode * findTwoNodeParent(treeNode *pRoot, int val01, int val02){
if(pRoot == NULL){
return NULL;
}
bool found01 = false;
bool found02 = false;
//值小的节点在左子树中查找 ,值大的节点在右子树中查找
int lval = val01 > val02 ? val02 : val01;
int rval = val01 < val02 ? val02 : val01;
found01 = hasNode(pRoot->pLeft, lval);
found02 = hasNode(pRoot->pRight, rval);
if(found01 && found02){
return pRoot;
}
treeNode * node = findTwoNodeParent(pRoot->pLeft, lval, rval);
if(node == NULL){
node = findTwoNodeParent(pRoot->pRight, lval, rval);
}
return node;
}
该算法效率不会很高,因为在判断节点是否存在时,会重复遍历每一个节点。
算法改进:如何才能不重复遍历每一个节点呢?
思路是:我们可以将遍历到的节点放到一个list中,这样就会生成一个从根节点到指定节点的链表,通过这样做,我们就把问题转换为寻找两个链表的最后一个公共节点的问题了,思路清晰了,开始写代码
//寻找从根节点到指定节点的路径
bool findPath(treeNode *pRoot, int val, list &path){
if(pRoot->data == val){
return true;
}
path.push_back(pRoot);
bool found = false;
if(pRoot->pLeft != NULL){
found = isHasNode(pRoot->pLeft, val, path);
}
if(!found && pRoot->pRight != NULL){
found = isHasNode(pRoot->pRight, val, path);
}
if(!found){
path.pop_back();
}
return found;
}生成了两个链表之后我们开始寻找最后一个公共节点
//由于两个链表的头节点是一样的,我们可以从头进行遍历,当不相等时,则返回上一个节点
treeNode * findLastCommonNode(listpath01, listpath02){
if(path01.empty() || path02.empty()){
return NULL;
}
list::iterator iter01 = path01.begin();
list::iterator iter02 = path02.begin();
treeNode *pNode;
while(*iter01 == *iter02){
pNode = *iter01;
iter01++;
iter02++;
}
return pNode;
}
treeNode * findTwoNodeCommonParent(treeNode *pRoot, int val01, int val02){
if(pRoot == NULL){
return NULL;
}
listpath01;
listpath02;
findPath(pRoot, val01, path01);
findPath(pRoot, val02, path02);
return findLastCommonNode(path01, path02);
}