之前我们知道怎么求根节点到某一子节点的路径。同理,要求两个子节点之间的路径,我们可以分别求出根节点到子节点的路径,然后合并路径即可(这是最直观的,应该还有更简单的方法)!
由于之前打印根节点到子节点的路径的函数返回后不能保存路径,所以修改如下,这样返回的path就保存了路径信息。
//寻找某一个特定的子节点
bool bLeafIsFound = false;//全局变量
void findPath(BinaryTreeNode*pRoot, vector<int>&path, int nToFind){
if (pRoot == NULL)
{
return;
}
path.push_back(pRoot->m_nValue);
if (!bLeafIsFound&&pRoot->m_nValue == nToFind) //达到了子节点
{
printPath(path);//打印路径
bLeafIsFound = true;
return; //已经找到了
}
if (!bLeafIsFound&&pRoot->m_pLeft != NULL)//左子树
{
findPath(pRoot->m_pLeft, path, nToFind);
}
if (!bLeafIsFound&&pRoot->m_pRight != NULL)//右子树
{
findPath(pRoot->m_pRight, path, nToFind);
}
if (!bLeafIsFound)//找到后就不弹出了
{
path.pop_back();//在返回到父节点之前,在路径上删除当前节点
}
}
找到两个子节点之间的路径:
//找到两个子节点之间的路径
void findPathOfTwoNode(BinaryTreeNode*pRoot,vector<int>& path,int nNodeOne,int nNodeTw0){
vector<int> path1;
vector<int> path2;
//得到两个节点的路径
findPath(pRoot, path1, nNodeOne);
bLeafIsFound = false;//全局变量复位
findPath(pRoot, path2, nNodeTw0);
bLeafIsFound = false;//全局变量复位
//常量迭代器
vector<int>::const_iterator iterOne=path1.begin();
vector<int>::const_iterator iterTwo=path2.begin();
int count=0;
while(iterOne != path1.end() && iterTwo != path2.end())
{
if (*iterOne==*iterTwo)
count++;//得到交点
++iterOne;
++iterTwo;
}
//归并两条路径
for (int i = path1.size() - 1; i >= 0;i--)
{
if (i> count-2)
{
path.push_back(path1[i]);
}
}
for (int i =0; i < path2.size(); i++)
{
if (i > count-1)
{
path.push_back(path2[i]);
}
}
}
//先序创建二叉树
void CreatBTree(BinaryTreeNode *&root)
{
int nValue = 0;
cin >> nValue;
if (-1 == nValue)
{
return;
}
else
{
root = new BinaryTreeNode();
root->m_nValue = nValue;
CreatBTree(root->m_pLeft);
CreatBTree(root->m_pRight);
}
}
int main(){
BinaryTreeNode*T;
cout << "先序构建二叉树:" << endl;
CreatBTree(T);
while (true)
{
cout << "输入两个子节点:" << endl;
int nNodeOne, nNodeTwo;
cin >> nNodeOne >> nNodeTwo;
cout << endl<< "打印二叉树两个子节点" << nNodeOne << "和" << nNodeTwo << "之间的路径:" << endl;
vector<int> path;
findPathOfTwoNode(T, path, nNodeOne, nNodeTwo);
cout << "归并后的路径:" << endl;
printPath(path);
path.clear();
}
}
以如下二叉树作为测试二叉树:
测试结果如下所示:
从结果可以看出,各种情况都满足!
另外,前面转载了一篇求节点最低公共祖先的文章,其实也可以用以上的方法来做,得到了俩个子节点的路径之后,从上往下遍历路径得到最后相交的节点就是最低公共祖先了!
代码如下:
//最低公共祖先
void lowestCommonAncestor(BinaryTreeNode*pRoot, int& nCommonNode,int nNodeOne, int nNodeTwo){
vector<int> path1;
vector<int> path2;
//得到两个节点的路径
findPath(pRoot, path1, nNodeOne);
bLeafIsFound = false;//全局变量复位
findPath(pRoot, path2, nNodeTwo);
bLeafIsFound = false;//全局变量复位
//常量迭代器
vector<int>::const_iterator iterOne = path1.begin();
vector<int>::const_iterator iterTwo = path2.begin();
while (iterOne != path1.end() && iterTwo != path2.end())
{
if (*iterOne == *iterTwo)
nCommonNode = *iterOne;
else{
break;//跳出循环
}
++iterOne;
++iterTwo;
}
}