您的位置:首页 > Web前端

剑指Offer学习总结-二叉树的镜像

2018-01-19 19:03 555 查看

剑指Offer学习总结-二叉树的镜像

本系列为剑指Offer学习总结,主要是代码案例的分析和实现:

书籍链接:http://product.dangdang.com/24242724.html

原作者博客:http://zhedahht.blog.163.com/blog/static/254111742011101624433132/

原作者博客链接有完整的项目代码下载。

二叉树的镜像

题目

题目:请完成一个函数, 输入一个二叉树, 该函数输出它的镜像

二叉树节点的定义如下:

struct BinaryTreeNode
{
int                    m_nValue;
BinaryTreeNode*        m_pLeft;
BinaryTreeNode*        m_pRight;
};


我们先用图来表示一个二叉树的镜像



仔细分析这两棵树的特点, 我们总结出求镜像的步骤这两棵树的根结点相同,

但它们的左右两个子结点交换了位置。 因此我们不妨先在树中交换根结点的两个子结点

交换根结点的两个结点之后, 我们注意到值为 10、 6 的结点的子结点仍然保持不变,

因此我们还需要交换这两个结点的左右子结点。

交换根结点的两个+结点之后, 我们注意到值为 10、 6 的结点的子

结点仍然保持不变, 因此我们还需要交换这两个结点的左右子结点。 交

换之后的结果分别是图中的第三棵树和第四棵树。 做完这两次交換之后,

我们已经遍历完所有的非叶子结点。 此时变换之后的树刚好就是原始树的镜像



常规的解法:

上边的思路,我们明显感觉到要使用递归来解决。

void MirrorRecursively(BinaryTreeNode *pNode)
{
//边界条件 节点为空或者节点没有左右孩子
if((pNode == NULL) || (pNode->m_pLeft == NULL && pNode->m_pRight==NULL))
return;

//交换左右孩子
BinaryTreeNode *pTemp = pNode->m_pLeft;
pNode->m_pLeft = pNode->m_pRight;
pNode->m_pRight = pTemp;

if(pNode->m_pLeft)
MirrorRecursively(pNode->m_pLeft);

if(pNode->m_pRight)
MirrorRecursively(pNode->m_pRight);
}


我们也可以用循环来改写递归,这里需要用到栈结构。

void MirrorIteratively(BinaryTreeNode* pRoot)
{
//异常参数处理
if(pRoot == NULL)
return;

std::stack<BinaryTreeNode*> stackTreeNode;
stackTreeNode.push(pRoot);

while(stackTreeNode.size() > 0)
{
BinaryTreeNode *pNode = stackTreeNode.top();
stackTreeNode.pop();

//从栈栈中取出需要操作的元素
BinaryTreeNode *pTemp = pNode->m_pLeft;
pNode->m_pLeft = pNode->m_pRight;
pNode->m_pRight = pTemp;

if(pNode->m_pLeft)
stackTreeNode.push(pNode->m_pLeft);

if(pNode->m_pRight)
stackTreeNode.push(pNode->m_pRight);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: