面试题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>
相关文章推荐
- C#实现获取系统目录并以Tree树叉显示的方法
- C语言实现输入一颗二元查找树并将该树转换为它的镜像
- 纯jsp打造无限层次的树代码
- 一波C语言二元查找树算法题目解答实例汇总
- php遍历树的常用方法汇总
- PHP树的深度编历生成迷宫及A*自动寻路算法实例分析
- PHP生成树的方法
- Java Swing中的表格(JTable)和树(JTree)组件使用实例
- python数据结构树和二叉树简介
- B+树到MySQL之innoDB
- ExtJS 4 树
- 数据库表TreeView树的快速生成
- Oracle 查询所有的父节点和子节点
- 多层级节点树实现
- 树的双亲存储:
- 树
- 二叉树(2)——遍历的非递归实现
- 二叉树(2)——遍历的非递归实现
- 二叉树(3)——三叉链表示的二叉树
- C#实现树结构