1 题目描述

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

2 输入描述:

二叉树的镜像定义:源二叉树
8
/ \
6 10
/ \ / \
5 7 9 11
镜像二叉树
8
/ \
10 6
/ \ / \
11 9 7 5

3 思路和方法

  (1)递归思想,先交换根节点的左右子树的位置,然后向下递归,把左右子树的根节点作为下次循环的根节点。

  (2)非递归:所以我们可以采用前序遍历的方法进行操作,每当遇到一个结点的时候,首先判断其是否有左右孩子(有其中之一即可),如果有的话,就交换其左右孩子,然后继续遍历其左右子树,只要不为空就继续交换其左右孩子节点(在交换具有孩子结点的结点的时候,其孩子结点也一并被交换了)。

4. C++核心代码

4.1 循环实现二叉树的镜像,利用栈的“后进先出”特性打印

 /*
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 *root) {
if (root == NULL)
return; stack<TreeNode*> stackTreeNode;
stackTreeNode.push(root); while (stackTreeNode.size() > )
{
TreeNode *parent = stackTreeNode.top();
stackTreeNode.pop(); TreeNode *Temp = parent->left;
parent->left = parent->right;
parent->right = Temp; if (parent->left)
stackTreeNode.push(parent->left);
if (parent->right)
stackTreeNode.push(parent->right);
}
}
};

4.2 递归实现二叉树的镜像,按照先序遍历,如果遇到空的节点或者叶子节点就返回,否则交换两个子树后再改变左右子树  

 /*
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 *pRroot) {
if (pRroot == NULL || (pRroot->left == NULL && pRroot->right == NULL))
return;
TreeNode * tmp = pRroot->left;
pRroot->left = pRroot->right;
pRroot->right = tmp; if (pRroot->left)
Mirror(pRroot->left);
if (pRroot->right)
Mirror(pRroot->right);
}
};

5. 完整代码

 #include<iostream>
#include<stack>
using namespace std; struct BinaryTreeNode
{
int data;
BinaryTreeNode* leftchild;
BinaryTreeNode* rightchild; BinaryTreeNode(int t)
{
data = t;
leftchild = NULL;
rightchild = NULL;
}
}; void PreorderTravel(BinaryTreeNode* root)
{
if (root == NULL)
{
return;
}
cout << root->data << " ";
PreorderTravel(root->leftchild);
PreorderTravel(root->rightchild);
} //递归实现二叉树的镜像,按照先序遍历,如果遇到空的节点或者叶子节点就返回,否则交换两个子树后再改变左右子树
void MirrorBinaryTree1(BinaryTreeNode* root)
{
if (root == NULL || (root->leftchild == NULL && root->rightchild == NULL))
{
return;
} BinaryTreeNode * tmp = root->leftchild;
root->leftchild = root->rightchild;
root->rightchild = tmp; if (root->leftchild)
{
MirrorBinaryTree1(root->leftchild);
}
if (root->rightchild)
{
MirrorBinaryTree1(root->rightchild);
} } //循环实现二叉树的镜像,利用栈的“后进先出”特性打印
void MirrorBinaryTree2(BinaryTreeNode* root)
{
if (root == NULL)
{
return;
} stack<BinaryTreeNode*> stackTreeNode;
stackTreeNode.push(root); while (stackTreeNode.size() > )
{
BinaryTreeNode *parent = stackTreeNode.top();
stackTreeNode.pop(); BinaryTreeNode *Temp = parent->leftchild;
parent->leftchild = parent->rightchild;
parent->rightchild = Temp; if (parent->leftchild)
{
stackTreeNode.push(parent->leftchild);
} if (parent->rightchild)
{
stackTreeNode.push(parent->rightchild);
} }
} // ====================测试代码==================== // 测试完全二叉树:除了叶子节点,其他节点都有两个子节点
// 8
// 6 10
// 5 7 9 11 BinaryTreeNode* root;
void Test1()
{
root = new BinaryTreeNode();
root->leftchild = new BinaryTreeNode();
root->rightchild = new BinaryTreeNode();
BinaryTreeNode* tmp = root->leftchild;
tmp->leftchild = new BinaryTreeNode();
tmp->rightchild = new BinaryTreeNode();
tmp = root->rightchild;
tmp->leftchild = new BinaryTreeNode();
tmp->rightchild = new BinaryTreeNode(); cout << "Test1:测试完全二叉树,除了叶子节点,其他节点都有两个子节点" << endl;
cout << "原二叉树的先序遍历" << endl;
PreorderTravel(root);
cout << endl; MirrorBinaryTree1(root);
cout << "二叉树镜像后的先序遍历" << endl;
PreorderTravel(root);
cout << endl; /*MirrorBinaryTree2(root);
cout << "二叉树镜像后的先序遍历" << endl;
PreorderTravel(root);
cout << endl;*/
} // 测试二叉树:出叶子结点之外,左右的结点都有且只有一个左子结点
// 8
// 7
// 6
// 5
//
void Test2()
{
root = new BinaryTreeNode();
root->leftchild = new BinaryTreeNode();
root->rightchild = NULL; BinaryTreeNode* tmp = root->leftchild;
tmp->leftchild = new BinaryTreeNode();
tmp->rightchild = NULL; tmp = tmp->leftchild;
tmp->leftchild = new BinaryTreeNode();
tmp->rightchild = NULL; tmp = tmp->leftchild;
tmp->leftchild = new BinaryTreeNode();
tmp->rightchild = NULL; cout << "Test2: 测试二叉树,出叶子结点之外,左右的结点都有且只有一个左子结点" << endl;
cout << "原二叉树的先序遍历" << endl;
PreorderTravel(root);
cout << endl; MirrorBinaryTree1(root);
cout << "二叉树镜像后的先序遍历" << endl;
PreorderTravel(root);
cout << endl; /*MirrorBinaryTree2(root);
cout << "二叉树镜像后的先序遍历" << endl;
PreorderTravel(root);
cout << endl;*/
} // 测试二叉树:出叶子结点之外,左右的结点都有且只有一个右子结点
// 8
// 7
// 6
// 5
// 4
void Test3()
{
root = new BinaryTreeNode();
root->leftchild = NULL;
root->rightchild = new BinaryTreeNode(); BinaryTreeNode* tmp = root->rightchild;
tmp->leftchild = NULL;
tmp->rightchild = new BinaryTreeNode(); tmp = tmp->rightchild;
tmp->leftchild = NULL;
tmp->rightchild = new BinaryTreeNode(); tmp = tmp->rightchild;
tmp->leftchild = NULL;
tmp->rightchild = new BinaryTreeNode(); cout << "Test3:测试二叉树出叶子结点之外,左右的结点都有且只有一个右子结点" << endl;
cout << "原二叉树的先序遍历" << endl;
PreorderTravel(root);
cout << endl; MirrorBinaryTree1(root);
cout << "二叉树镜像后的先序遍历" << endl;
PreorderTravel(root);
cout << endl; /*MirrorBinaryTree2(root);
cout << "二叉树镜像后的先序遍历" << endl;
PreorderTravel(root);
cout << endl;*/
} // 测试空二叉树:根结点为空指针
void Test4()
{
root = NULL; cout << "Test4:测试空二叉树,根结点为空指针" << endl;
cout << "原二叉树的先序遍历" << endl;
PreorderTravel(root);
cout << endl; MirrorBinaryTree1(root);
cout << "二叉树镜像后的先序遍历" << endl;
PreorderTravel(root);
cout << endl; /*MirrorBinaryTree2(root);
cout << "二叉树镜像后的先序遍历" << endl;
PreorderTravel(root);
cout << endl;*/
} // 测试只有一个结点的二叉树
void Test5()
{
root = new BinaryTreeNode();
root->leftchild = NULL;
root->rightchild = NULL; cout << "Test5:测试只有一个结点8的二叉树" << endl;
cout << "原二叉树的先序遍历" << endl;
PreorderTravel(root);
cout << endl; MirrorBinaryTree1(root);
cout << "二叉树镜像后的先序遍历" << endl;
PreorderTravel(root);
cout << endl; /*MirrorBinaryTree2(root);
cout << "二叉树镜像后的先序遍历" << endl;
PreorderTravel(root);
cout << endl;*/
} int main()
{
Test1();
Test2();
Test3();
Test4();
Test5(); system("pause");
return ;
}

参考资料

https://blog.csdn.net/yanxiaolx/article/details/52019871



最新文章

  1. 安装numpy
  2. Eclipse 文本显示行号
  3. bzoj3668: [Noi2014]起床困难综合症
  4. HTML5区域范围文本框实例页面
  5. python(进程池/线程池)
  6. swift之向ftp服务器传文件
  7. Java string和各种格式互转 string转int int转string
  8. [BZOJ]4650 优秀的拆分(Noi2016)
  9. 基于异步队列的生产者消费者C#并发设计
  10. linux下SS 网络命令详解
  11. Java——代码复用(组合和继承)
  12. spring Onions and wine
  13. VBA 删除Excel中所有的图片
  14. [译]Nuget.Server
  15. Celery配置实践笔记
  16. gem &quot;ransack&quot;(4000✨) 简单介绍
  17. Codeforces Beta Round #75 (Div. 2 Only)
  18. Latex数学公式编写
  19. SVN迁移部署
  20. Java编译命令整理

热门文章

  1. Android Jenkins 自动化打包构建
  2. Linux之防火墙【CentOS 7】
  3. gensim word2vec实践
  4. SQL-W3Chool-高级:SQL CREATE DATABASE 语句
  5. Android 显示系统:SurfaceFlinger详解
  6. [SQL]as的是否可以省略的问题
  7. [Scikit-learn] 1.1 Generalized Linear Models - Neural network models
  8. SQL查询交集、并集、差集
  9. JAVA-开发构建Gradle项目安装使用教程
  10. Vue学习笔记(三)组件间如何通信传递参数