注:此方法采用BSF
思路,先判断入口是否有非法输入。
1 如果某一个root==p || root == q,那么LCA肯定是root(因为是top down,LCA肯定在root所囊括的树上,而root又是p q其中一个节点了,那么另外一个节点肯定在root之下,那么root就是LCA),那么返回root
2 如果root<min(p, q),那么LCA肯定在右子树上,那么递归
3 如果max(p, q)<root,那么LCA肯定在左子树上,那么递归
4 如果p<root<q,那么root肯定为LCA
#include <iostream>
using namespace std;
typedef struct{
int value;
Node *pLeft;
Node *pRight;
}Node;
Node* LCA(Node *root, Node *p, Node *q)
{
if (!root || !p || !q) // 注意还要判断p和q是否为NULL
return NULL;
if (root->value == p->value || root->value == q->value) //这一行可以调整到最后,和最后一个return root(注释①)合并起来
return root;
if (root->value < p->value && root->value < q->value)
return LCA(root->pRight, p, q);
if (root->value > p->value && root->value > q->value)
return LCA(root->pLeft, p, q);
return root; //①
}
int main()
{
//此处为测试代码
}
然后发现有2个逻辑分支可以合并,就是1 4,都是返回root,所以可以把1 4合并,这里直接给出官方solution,自己就不再optimize了
Node *LCA(Node *root, Node *p, Node *q) {
if (!root || !p || !q) return NULL;
if (max(p->data, q->data) < root->data)
return LCA(root->left, p, q);
else if (min(p->data, q->data) > root->data)
return LCA(root->right, p, q);
else
return root;
}
除此之外,还要确认一下 p q是否一定是root下层的某个孩子,如果不一定是,那么需要自己写个Check函数
bool Check(Node *root, Node *pNode)
{
if (!root || !pNode)
return NULL;
while (root->value != pNode->value) // 这里一定要用一个pTemp来指向root来进行遍历,因为你改变了root,就给调用者造成了麻烦!
{
if (!root) // 这个可以合并到while()的判断条件中去,使得这个循环有2种情况下退出:
// 1 pTemp和pNode的value相等
// 2 root已经是叶子节点的子节点了,那就不用再往下走了
break;
if (root->value > pNode->value)
root = root->pLeft;
else if (root->value < pNode->value)
root = root->pRight;
}
if (!root)
return false;
else if (root->value == pNode->value)
return true;
}
参考网址:
http://www.leetcode.com/2011/07/lowest-common-ancestor-of-a-binary-search-tree.html
原文链接:http://www.cnblogs.com/lihaozy/archive/2012/12/03/2799408.html