1、求二叉树的镜像
递归解法:
(1)如果二叉树为空,返回空
(2)如果二叉树不为空,求左子树和右子树的镜像,然后交换左子树和右子树
参考代码如下:
BinaryTreeNode * Mirror(BinaryTreeNode * pRoot)
{
if(pRoot == NULL)
return NULL;
BinaryTreeNode * pLeft = Mirror(pRoot->m_pLeft);
BinaryTreeNode * pRight = Mirror(pRoot->m_pRight);
pRoot->m_pLeft = pRight;
pRoot->m_pRight = pLeft;
return pRoot;
}
2、求二叉树中两个节点的最低公共祖先节点
递归解法:
(1)如果两个节点分别在根节点的左子树和右子树,则返回根节点
(2)如果两个节点都在左子树,则递归处理左子树;如果两个节点都在右子树,则递归处理右子树
参考代码如下:
bool FindNode(BinaryTreeNode * pRoot, BinaryTreeNode * pNode)
{
if(pRoot == NULL || pNode == NULL)
return false;
if(pRoot == pNode)
return true;
bool found = FindNode(pRoot->m_pLeft, pNode);
if(!found)
found = FindNode(pRoot->m_pRight, pNode);
return found;
}
BinaryTreeNode * GetLastCommonParent(BinaryTreeNode * pRoot,
BinaryTreeNode * pNode1,
BinaryTreeNode * pNode2)
{
if(FindNode(pRoot->m_pLeft, pNode1))
{
if(FindNode(pRoot->m_pRight, pNode2))
return pRoot;
else
return GetLastCommonParent(pRoot->m_pLeft, pNode1, pNode2);
}
else
{
if(FindNode(pRoot->m_pLeft, pNode2))
return pRoot;
else
return GetLastCommonParent(pRoot->m_pRight, pNode1, pNode2);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
分析:
递归解法效率很低,有很多重复的遍历,下面看一下非递归解法。
非递归解法:
先求从根节点到两个节点的路径,然后再比较对应路径的节点就行,最后一个相同的节点也就是他们在二叉树中的最低公共祖先节点
参考代码如下:
bool GetNodePath(BinaryTreeNode * pRoot, BinaryTreeNode * pNode,
list<BinaryTreeNode *> & path)
{
if(pRoot == pNode)
{
path.push_back(pRoot);
return true;
}
if(pRoot == NULL)
return false;
path.push_back(pRoot);
bool found = false;
found = GetNodePath(pRoot->m_pLeft, pNode, path);
if(!found)
found = GetNodePath(pRoot->m_pRight, pNode, path);
if(!found)
path.pop_back();
return found;
}
BinaryTreeNode * GetLastCommonParent(BinaryTreeNode * pRoot, BinaryTreeNode * pNode1, BinaryTreeNode * pNode2)
{
if(pRoot == NULL || pNode1 == NULL || pNode2 == NULL)
return NULL;
list<BinaryTreeNode*> path1;
bool bResult1 = GetNodePath(pRoot, pNode1, path1);
list<BinaryTreeNode*> path2;
bool bResult2 = GetNodePath(pRoot, pNode2, path2);
if(!bResult1 || !bResult2)
return NULL;
BinaryTreeNode * pLast = NULL;
list<BinaryTreeNode*>::const_iterator iter1 = path1.begin();
list<BinaryTreeNode*>::const_iterator iter2 = path2.begin();
while(iter1 != path1.end() && iter2 != path2.end())
{
if(*iter1 == *iter2)
pLast = *iter1;
else
break;
iter1++;
iter2++;
}
return pLast;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
在上述算法的基础上稍加变化即可求二叉树中任意两个节点的距离了。
3、求二叉树中节点的最大距离
即二叉树中相距最远的两个节点之间的距离。
递归解法:
(1)如果二叉树为空,返回0,同时记录左子树和右子树的深度,都为0
(2)如果二叉树不为空,最大距离要么是左子树中的最大距离,要么是右子树中的最大距离,要么是左子树节点中到根节点的最大距离+右子树节点中到根节点的最大距离,同时记录左子树和右子树节点中到根节点的最大距离。
参考代码如下:
int GetMaxDistance(BinaryTreeNode * pRoot, int & maxLeft, int & maxRight)
{
if(pRoot == NULL)
{
maxLeft = 0;
maxRight = 0;
return 0;
}
int maxLL, maxLR, maxRL, maxRR;
int maxDistLeft, maxDistRight;
if(pRoot->m_pLeft != NULL)
{
maxDistLeft = GetMaxDistance(pRoot->m_pLeft, maxLL, maxLR);
maxLeft = max(maxLL, maxLR) + 1;
}
else
{
maxDistLeft = 0;
maxLeft = 0;
}
if(pRoot->m_pRight != NULL)
{
maxDistRight = GetMaxDistance(pRoot->m_pRight, maxRL, maxRR);
maxRight = max(maxRL, maxRR) + 1;
}
else
{
maxDistRight = 0;
maxRight = 0;
}
return max(max(maxDistLeft, maxDistRight), maxLeft+maxRight);
}