完成一个函数,输入一个二叉树,该函数输出它的镜像。
分析:
- 画图看出,对每个非叶结点,需要交换其左子树和右子树位置。
- 操作相同,可采用递归解决。
代码:
#include <iostream>
using namespace std;
struct BinaryTreeNode
{
int valuel;
BinaryTreeNode * pLeft;
BinaryTreeNode * pRight;
};
void MirrorRecursively(BinaryTreeNode * pNode)
{
// 检查输入的有效性
if (pNode == nullptr)
return;
// 如果左子树和右子树均为空,则递归结束
if (pNode->pLeft == nullptr && pNode->pRight == nullptr)
return;
// 递归主体:左右交换
BinaryTreeNode * ptmp = pNode->pLeft;
pNode->pLeft = pNode->pRight;
pNode->pRight = ptmp;
// 递归调用左子树
if (pNode->pLeft)
MirrorRecursively(pNode->pLeft);
// 递归调用右子树
if (pNode->pRight)
MirrorRecursively(pNode->pRight);
}
扩展:上述采用递归实现,改为非递归如何实现?
分析:递归本质上就是使用栈,此时代码隐式使用栈。采用非递归时,相当于显示使用栈。则首先将根节点压栈,然后while循环中当栈不空时,弹出栈顶,并交换该栈顶元素的左右子树,若左右子树不为空,则将左右节点压栈。
void MirrorNoRecursively(BinaryTreeNode * pNode)
{
if (pNode == nullptr)
return;
stack<BinaryTreeNode *> stackNode;
stackNode.push(pNode);
// 当栈不空,存在非叶结点
while (stackNode.size())
{
// 弹出栈顶,并交换其左右
BinaryTreeNode * tree = stackNode.top();
stackNode.pop();
if (tree->pLeft != nullptr && tree->pRight != nullptr)
{
BinaryTreeNode * ptmp = tree->pLeft;
tree->pLeft = tree->pRight;
tree->pRight = ptmp;
}
// 若左右不空,则压栈待交换。
// 类似于层次遍历:出父节点时,其左右子树的根节点入排在后面
if (tree->pLeft)
stackNode.push(tree->pLeft);
if (tree->pRight)
stackNode.push(tree->pRight);
}
}