您的位置:首页 > 职场人生

面试题50:二叉树中两个节点的最低公共祖先

2016-05-31 20:24 597 查看
<pre name="code" class="plain"><span style="font-size:14px;">#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef struct BtNode
{
int value;
struct BtNode *lchild;
struct BtNode *rchild;
}BtNode, *Bitree;

Bitree newBtNode()
{
Bitree p = new BtNode;

if( NULL == p )
{
cout << "newBtNode func: err -1, NULL==p " << endl;
return p;
}

p->value = 0;
p->lchild = p->rchild = NULL;
return p;
}

int createBitree( Bitree *head )
{
int ret = 0;

if( NULL == head )
{
cout << "createBitree func: err -1, NULL==head" << endl;
ret = -1;
return ret;
}

int data = 0;
cin >> data;

if( 0 == data ) // leaf
{
*head = NULL;
}
else
{
*head = newBtNode();
(*head)->value = data;
createBitree( &( (*head)->lchild ) );
createBitree( &( (*head)->rchild ) );
}

return ret;

}

void preTravel( Bitree head )
{
if( head != NULL )
{
cout << head->value << ' ';
preTravel( head->lchild );
preTravel( head->rchild );
}

return;
}

void midTravel( Bitree head )
{
if( head != NULL )
{
midTravel( head->lchild );
cout << head->value << ' ';
midTravel( head->rchild );
}

return;
}

void postTravel( Bitree head )
{
if( head != NULL )
{
postTravel( head->lchild );
postTravel( head->rchild );
cout << head->value << ' ';
}

return;
}

// 找出二叉树中的两个结点的最低公共祖先
Bitree findLastCommonNode( Bitree head, int value1, int value2 )
{
Bitree pRet = NULL;

if( NULL == head )
{
cout << "findLastCommonNode func: err -1, NULL==head" << endl;
return pRet;
}

if( ( value1 < head->value && head->value < value2 ) || ( value2 < head->value && head->value < value1 ) )
{
pRet = head;
return pRet;
}
else if( head->value > value1 && head->value > value2 ) // 当前节点比要找的两个节点的值大,从左子树递归查找
{
if( NULL == head->lchild )
{
cout << "findLastCommonNode func: can not find the two nodes in bitree" << endl;
return pRet;
}

return findLastCommonNode( head->lchild, value1, value2 );
}
else if( head->value < value1 && head->value < value2 ) // 当前节点比要找的两个节点的值小,右子树递归查找
{
if( NULL == head->lchild )
{
cout << "findLastCommonNode func: can not find the two nodes in bitree" << endl;
return pRet;
}

return findLastCommonNode( head->rchild, value1, value2 );

}

cout << "findLastCommonNode func: err, value1 = " << value1 << ", value2 = " << value2 << endl;

return pRet;
}

// 在二叉树中查找是否存在该节点
Bitree checkIsInBiTree( Bitree root, int value )
{
Bitree pTarget = NULL;

if( NULL == root )
{
cout << "checkIsInBiTree( Bitree root, int value ) func: err -1, NULL==root, value = " << value << endl;
return pTarget;
}

if( root->value == value )
{
pTarget = root;
return pTarget;
}
else if( root->value < value && root->rchild != NULL )
{
return checkIsInBiTree( root->rchild, value );
}
else if( root->value > value && root->lchild != NULL )
{
return checkIsInBiTree( root->lchild, value );
}
else
{
return pTarget;
}
}

int checkValid( Bitree root, int value1, int value2, Bitree *pFirstNode )
{
int ret = 0;

if( NULL == root || NULL == pFirstNode )
{
cout << " checkValid func: err -1,NULL == root || NULL == pFirstNode " << endl;
ret = -1;
return ret;
}

if( value1 == value2 )
{
Bitree p1 = checkIsInBiTree( root, value1 );

if( NULL == p1 )
{
ret = -1;
return ret;
}
else
{
Bitree p2 = NULL;

if( p1->lchild != NULL )
{
p2 = checkIsInBiTree( p1->lchild, value2 );
}
else if( p1->rchild != NULL )
{
p2 = checkIsInBiTree( p1->rchild, value2 );
}

if( NULL == p2 )
{
ret = -1;
return ret;
}
else
{
*pFirstNode = p1;
ret = 1;  // value2节点是value1的子节点
}

}
}
else
{
Bitree p1 = checkIsInBiTree( root, value1 );
Bitree p2 = checkIsInBiTree( root, value2 );

if( NULL == p1 || NULL == p2 )
{
ret = -1;
return ret;
}

//bool isChild = false;

if( p1->lchild != NULL )
{
if( checkIsInBiTree( p1->lchild, value2 ) != NULL )
{
*pFirstNode = p1;
ret = 1;
}
}

// 查找是否value1是value2的子节点,或value2是value1的子节点
if( p1->rchild != NULL )
{
if( checkIsInBiTree( p1->rchild, value2 ) != NULL )
{
*pFirstNode = p1;
ret = 1;
}
}

if( p2->lchild != NULL )
{
if( checkIsInBiTree( p2->lchild, value1 ) != NULL )
{
*pFirstNode = p2;
ret = 1;
}
}

if( p2->rchild != NULL )
{
if( checkIsInBiTree( p2->rchild, value1 ) != NULL )
{
*pFirstNode = p2;
ret = 1;
}
}

}

return ret;
}

Bitree findParentOfChildByValue( Bitree root, int child )
{
Bitree parent = NULL;

if( NULL == root )
{
cout << "findParentOfChild func: err -1, NULL==root " << endl;
return parent;
}

if( root->lchild != NULL && root->lchild->value == child )
{
parent = root;
return parent;
}
else if( root->rchild != NULL && root->rchild->value == child )
{
parent = root;
return parent;
}
else if( root->lchild != NULL && root->value > child )
{
return findParentOfChildByValue( root->lchild, child );
}
else if( root->rchild != NULL && root->value < child )
{
return findParentOfChildByValue( root->rchild, child );
}
else
{
return parent;
}

}

Bitree findParentOfChildByPointer( Bitree root, Bitree child )
{
Bitree parent = NULL;

if( NULL == root || NULL == child )
{
cout << "findParentOfChildByPointer func: err -1, NULL==root || NULL == child " << endl;
return parent;
}

if( root->lchild == child || root->rchild == child )
{
parent = root;
return parent;
}
else if( root->lchild != NULL && root->value > child->value )
{
return findParentOfChildByPointer( root->lchild, child );
}
else if( root->rchild != NULL && root->value < child->value )
{
return findParentOfChildByPointer( root->rchild, child );
}
else
{
return parent;
}

}

// 在二叉树(并不需要是排序二叉树)中查找value的节点,并返回指向该节点的指针,没找到返回NULL
Bitree getNodeByValue( Bitree root, int value )
{
Bitree pRet = NULL;

if( NULL == root )
{
cout << "getNodeByValue func: err -1, NULL==root" << endl;
return pRet;
}

if( root->value == value )
{
pRet = root;
return pRet;
}
else
{
Bitree pLeftResult = NULL;
Bitree pRightResult = NULL;

if( root->lchild != NULL )
{
pLeftResult = getNodeByValue( root->lchild, value );
}

if( pLeftResult != NULL ) // 找到了
{
pRet = pLeftResult;
return pRet;
}

if( root->rchild != NULL )
{
pRightResult = getNodeByValue( root->rchild, value );
}

if( pRightResult != NULL ) // 找到了
{
pRet = pRightResult;
return pRet;
}
else
{
return pRet;
}

}

}

// 查找从根节点到pNode节点的路径
vector<Bitree> getNodePathFromRoot( Bitree root, Bitree pNode, vector<Bitree> curPath )
{
vector<Bitree> path;

if( NULL == root || NULL == pNode )
{
cout << "getNodePathFromRoot func: err -1, NULL == root || NULL == pNode" << endl;
return path;
}

if( root == pNode )
{
curPath.push_back( root );
return curPath;
}

Bitree pleft = root->lchild;
Bitree pright = root->rchild;
vector<Bitree> leftResult;
vector<Bitree> rightResult;

curPath.push_back( root );

if( pleft != NULL )
{
leftResult = getNodePathFromRoot( pleft, pNode, curPath );
}

if( pright != NULL )
{
rightResult = getNodePathFromRoot( pright, pNode, curPath );
}

if( leftResult.size() > 0 && leftResult[ leftResult.size() - 1 ] == pNode )
{
//cout << "find in leftTree" << endl;
return leftResult;
}

if( rightResult.size() > 0 && rightResult[ rightResult.size() - 1 ] == pNode )
{
//cout << "find in rightTree" << endl;
return rightResult;
}

return path;
}

//查找从根节点到pNode节点的路径
//返回0表示查找成功,-1表示查找失败
int getNodePathFromRoot1( Bitree root, Bitree pNode, vector<Bitree> &path )
{
int ret = 0;

if( NULL == root || NULL == pNode )
{
cout << "getNodePathFromRoot1 func: err -1, NULL == root || NULL == pNode" << endl;
ret = -1;
return ret;
}

if( root == pNode ) // 查找到了
{
path.push_back(root);
return ret;
}

path.push_back(root);

Bitree pleft = root->lchild;
Bitree pright = root->rchild;

int found = -1;

if( pleft != NULL )
{
int ret1 = getNodePathFromRoot1( pleft, pNode, path ); // 从左子树查找

if( 0 == ret1 )
{
ret = ret1;
return ret;
}
}

if( pright != NULL )
{
int ret2 = getNodePathFromRoot1( pright, pNode, path ); // 从右子树查找

if( 0 == ret2 )
{
ret = ret2;
return ret;
}
}

path.pop_back(); // 左右子树都没有找到就弹出当前元素
ret = -1;
return ret; // 返回查找失败的标志

}

int main()
{
int ret = 0;

Bitree root = NULL;
createBitree( &root );

preTravel(root);
cout << endl;

midTravel(root);
cout << endl;

postTravel(root);
cout << endl;

cout << "============================" << endl << endl;

int value1 = 0;
int value2 = 0;
Bitree pFirstNode = NULL;
/*
while( cin >> value1 )
{
Bitree pNode = getNodeByValue( root, value1 );
vector<Bitree> curPath;
//vector<Bitree> path = getNodePathFromRoot( root, pNode, curPath );
getNodePathFromRoot1( root, pNode, curPath );

int len = curPath.size();

for( int i = 0; i < len; ++i )
{
cout << curPath[i]->value << ' ';
}
cout << endl;
}*/

while( cin >> value1 >> value2 )
{

int status = checkValid( root, value1, value2, &pFirstNode );

if( status < 0 )
{
cout << "main func: err -1, can not find " << value1 << " or " << value2 << endl;
continue;
}
else if( 1 == status ) // 一个节点为另外一个节点的子节点
{
if( value1 == value2 )
{

if( root->value == value1 ) //为父亲节点
{
cout << "no common node with " << value1 << " and " << value2 << endl;
continue;
}

Bitree parent = findParentOfChildByValue( root, value1 );

if( parent != NULL )
{
cout << "common Node: " << parent->value << endl;
}
else
{
cout << "can not find common node with " << value1 << " and " << value2 << endl;
}

continue;
}
else
{
if( root == pFirstNode )
{
cout << "no common node with " << value1 << " and " << value2 << endl;
continue;
}

Bitree parent = findParentOfChildByPointer( root, pFirstNode );

if( parent != NULL )
{
cout << "common Node: " << parent->value << endl;
}
else
{
cout << "can not find common node with " << value1 << " and " << value2 << endl;
}

continue;
}
}
else            // status = 0
{
//cout << "will call findLastCommonNode" << endl;
//cout << pFirstNode->value << endl;
Bitree result = findLastCommonNode( root, value1, value2 );
cout << "common Node: " << result->value << endl;
continue;
}

}

return ret;
}

/*

10
/  \
5    15
/\     /\
3  8   12 16
/   /\
1  6  9

./a.out
10 5 3 1 0 0 0 8 6 0 0 9 0 0 15 12 0 0 16 0 0
10 5 3 1 8 6 9 15 12 16
1 3 5 6 8 9 10 12 15 16
1 3 6 9 8 5 12 16 15 10
============================

1 3
common Node: 5
3 6
common Node: 5
3 15
common Node: 10
3 12
common Node: 10
1 16
common Node: 10
6 9
common Node: 8
3 8
common Node: 5
5 6
common Node: 10
1 2
main func: err -1, can not find 1 or 2
22 11
main func: err -1, can not find 22 or 11

*/

</span>



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  公共祖先