1、二叉树定义:
typedef struct BTreeNodeElement_t_ {
void *data;
} BTreeNodeElement_t;
typedef struct BTreeNode_t_ {
BTreeNodeElement_t *m_pElemt;
struct BTreeNode_t_ *m_pLeft;
struct BTreeNode_t_ *m_pRight;
} BTreeNode_t;2、查找二叉树中两个节点的最低祖先节点(或最近公共父节点等)
最低祖先节点就是从根节点遍历到给定节点时的最后一个相同节点
例如:
A
B C
D E F G
H I J K L M N O
如上图,H和J的最低祖先节点是B。
因为从根节点A到H的链路为: A B D H
从根节点A到J的链路为: A B E J
查看链路节点可知,B是最后一个相同节点,也就是所谓的最近公共父节点或者说最低祖先节点。
(1)递归方式
如果给定pRoot是NULL,即空树,则返回的公共节点自然就是NULL;
如果给定pRoot与两个节点中任何一个相同,说明,pRoot在就是所要找的两个节点之一,则直接返回pRoot,表明在当前链路中找到至少一个节点;
如果给定pRoot不是两个节点中任何一个,则说明,需要在pRoot的左右子树中重新查找,此时有三种情况:两个节点都在左子树上;两个节点都在右子树上;一个在左子树,一个在右子树上;具体来说,就是:
情况一:如果左子树查找出的公共节点是NULL,则表明从左子树根节点开始到左子树的所有叶子节点等所有节点中,没有找到两个节点中的任何一个,这就说明,这两个节点不在左子树上,不在左子树,则必定在右子树上;
情况二:如果右子树查找的公共节点是NULL,说明在右子树中无法找到任何一个节点,则两个节点必定在左子树上;
情况三: 如果左右子树查找的公共节点都不是NULL,说明左右子树中各包含一个节点,则当前节点pRoot就是最低公共节点,返回就可以了。
三种情况是互斥的, 只能是其中之一。
BTreeNode_t *GetLastCommonParent( BTreeNode_t *pRoot, BTreeNode_t *pNode1, BTreeNode_t *pNode2){
if( pRoot == NULL ) //说明是空树,不用查找了,也就找不到对应节点,则返回NULL
return NULL;
if( pRoot == pNode1 || pRoot == pNode2 )//说明在当前子树的根节点上找到两个节点之一
return pRoot;
BTreeNode_t *pLeft = GetLastCommonParent( pRoot->m_pLeft, pNode1, pNode2); //左子树中的查找两个节点并返回查找结果
BTreeNode_t *pRight = GetLastCommonParent( pRoot->m_pRight, pNode1, pNode2);//右子树中查找两个节点并返回查找结果
if( pLeft == NULL )//如果在左子树中没有找到,则断定两个节点都在右子树中,可以返回右子树中查询结果;否则,需要结合左右子树查询结果共同断定
return pRight;
if ( pRight == NULL )//如果在右子树中没有找到,则断定两个节点都在左子树中,可以返回左子树中查询结果;否则,需要结合左右子树查询结果共同断定
return pLeft;
return pRoot;//如果在左右子树中都找两个节点之一,则pRoot就是最低公共祖先节点,返回即可。
}
(2)非递归方式:
二叉树(12)----查找两个节点最低祖先节点(或最近公共父节点等),递归和非递归
原文:http://blog.csdn.net/beitiandijun/article/details/41970417