您的位置:首页 > 编程语言 > C语言/C++

算法学习记录十四(C++)--->二叉树的镜像

2017-09-29 14:08 567 查看

描述

操作给定的二叉树,将其变换为源二叉树的镜像。



分析

我们只需要遍历二叉树,然后每次访问(输出)一个节点的时候。交换其左右孩子即可

有递归和非递归两个版本

其本质是相同的,就是把前序中序,后序遍历中的打印节点的过程,编程交换左右子树的过程,其中需要注意一点,就是交换后左右子树进行了交换,再往下走的时候,往左走往右走的过程需改变,原来的向右走,现在应该是向左走

递归版本

/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
// 递归
class Solution {
public:
void Mirror(TreeNode *pRoot) {
if(pRoot == NULL){
return;
}
swap(pRoot->left,pRoot->right);
Mirror(pRoot->left);
Mirror(pRoot->right);

}
};


非递归版本(前序)

// 前序 前序遍历的过程中,先根,再左再右,
// 由于根后面才对左右子树进行访问,因此访问顺序可不交换,我们此时的访问顺序依旧是根左右,但是对应原来的根右左
class Solution {
public:
void Mirror(TreeNode *pRoot) {
if(pRoot == NULL){
return;
}
// 栈
stack<TreeNode *> nStack;
// 压根节点入栈
nStack.push(pRoot);
// 根节点
TreeNode *node = pRoot;
// 一开始栈里面有根节点 不为空
while(nStack.empty() != true){
// 获取栈顶元素
node = nStack.top();
nStack.pop();
// 交换
if(node->left != NULL || node->right != NULL){
swap(node->left,node->right);
}
// 递归左子树
if(node->left != NULL){
nStack.push(node->left);
}
// 递归右子树
if(node->right != NULL){
nStack.push(node->right);
}
}

}
};


非递归版本(中序)

class Solution {
public:
// 中序 中序遍历的时候,访问顺序左根右,由于访问后,依然要向右走,
// 所以交换后,变成了向左走 也就是最后一段代码的体现
void Mirror(TreeNode *pRoot) {
if(pRoot == NULL){
return;
}
// 栈
stack<TreeNode *> nStack;
// 根节点
TreeNode *node = pRoot;
// 节点空 而且 栈为空 结束循环
while(node != NULL || nStack.empty() != true){
// 二叉树左侧所有节点入栈  例如第一次是 865
while(node != NULL){
nStack.push(node);
node = node->left;
}
// 865一个个出栈
while(nStack.empty() != true){
node = nStack.top();
// 出栈的过程中进行交换左右
if(node->left != NULL || node->right != NULL){
swap(node->left,node->right);
}
nStack.pop();
// 最关键的一句 由于左侧所有节点已经左右交换完毕,因此你不会再去获取node->right,不然你操作的又是刚才的节点
// 应该继续node->left的左子树进行下一轮
node = node->left;
}
}

}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息