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



剑指offer18:操作给定的二叉树,将其变换为源二叉树的镜像。的更多相关文章

  1. 剑指Offer-18.二叉树的镜像(C++/Java)

    题目: 题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ ...

  2. 二叉树的镜像(剑指offer-18)

    题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 解析 先前序遍历这棵树的每个结点,如果遍历到的结点有子结点,就交换它的两个子节点, 当交换完所有的非叶子结点的左右子结点之后,就得到了树的镜像 ...

  3. C++版 - 剑指offer 面试题23:从上往下打印二叉树(二叉树的层次遍历BFS) 题解

    剑指offer  面试题23:从上往下打印二叉树 参与人数:4853  时间限制:1秒  空间限制:32768K 提交网址: http://www.nowcoder.com/practice/7fe2 ...

  4. 【javascript】操作给定的二叉树,将其变换为源二叉树的镜像。

    操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ 11 9 ...

  5. 剑指Offer的学习笔记(C#篇)-- 平衡二叉树(二叉树后序遍历递归详解版)

    题目描述 输入一棵二叉树,判断该二叉树是否是平衡二叉树. 一 . 题目分析 首先要理解一个概念:什么是平衡二叉树,如果某二叉树中任意的左右子树深度相差不超过1,那么他就是一颗平衡二叉树.如下图: 所以 ...

  6. 剑指OFFER18 判断一个二叉树的子树

    public class a18_IsSubTree { public static boolean hasSubTree(TreeNode treeRoot1, TreeNode treeRoot2 ...

  7. 剑指Offer面试题:21.从上到下打印二叉树

    一.题目:从上到下打印二叉树 题目:从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印.例如输入下图中的二叉树,则依次打印出8.6.10.5.7.9.11. 二叉树节点的定义如下,采用 ...

  8. 剑指offer面试题23:从上到下打印二叉树(树的层序遍历)

    题目:从上往下打印出二叉树的每个节点,同一层的结点按照从左往右的顺序打印. 解题思路:二叉树的层序遍历,在打印一个节点的时候,要把他的子节点保存起来打印第一层要把第二层的节点保存起来, 打印第二层要把 ...

  9. 剑指offer-字符的所有组合,复制复杂链表,二叉树中和为某一值的路径

    字符的所有组合 描述: 输入一个字符串,求这个字符串中的字符的所有组合.如:"abc",组合为"a" "b" c" "a ...

随机推荐

  1. Robot Framework(十八) 支持工具

    5支持工具 5.1库文档工具(libdoc) libdoc是一种用于为HTML和XML格式的测试库和资源文件生成关键字文档的工具.前一种格式适用于人类,后者适用于RIDE和其他工具.Libdoc也没有 ...

  2. 修复grub rescue问题

    前几天,手欠点了下win10的系统升级,直接从17.09升级到了19.3虽然也有些波折,总体顺利,以为一切都完事大吉之时,重启系统,原来,万恶的win10给我挖好了坑,早等着我呢.我去,千万只cnm脑 ...

  3. 爬虫之代理和cookie的处理

    代理操作 代理的目的 为解决ip被封的情况 什么是代理 代理服务器:fiddler 为什么使用代理可以改变请求的ip 本机的请求会先发送给代理服务器,代理服务器会接受本机发送过来的请求(当前请求对应的 ...

  4. 进程 | 线程 | 当Linux多线程遭遇Linux多进程

    背景 本文并不是介绍Linux多进程多线程编程的科普文,如果希望系统学习Linux编程,可以看[<Unix环境高级编程>第3版] 本文是描述多进程多线程编程中遇到过的一个坑,并从内核角度分 ...

  5. Kombu is a messaging library for Python.

    https://kombu.readthedocs.io/en/stable/introduction.html

  6. [go]grpc远程接口调用实现

    // grpc序列化/反序列化成对应语言的对象 // 1.写idl(数据类型+方法) // 2.生成对应语言的序列化/反序列化代码 // 3.方法需要自己实现 // 环境(将gopath/bin加入p ...

  7. C之数据类型

    java的数据类型 byte 1个字节 boolean 1个字节 short 2个字节 char 2个字节 int 4个字节 float 4个字节 long 8个字节 double 8个字节 c语言的 ...

  8. UC浏览器打开百度显示 丰臣吉秀.网址

  9. OpenStack 虚拟机热迁移流程图

    目录 文章目录 目录 源计算节点与目的计算节点之间的交互流程 Nova 和 Neutron 之间的交互流程 源计算节点与目的计算节点之间的交互流程 热迁移主要包括三个阶段: pre_live_migr ...

  10. mysql软件升降级及配置参数

    1.下载mysql5.7的软件 https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.20-linux-glibc2.12-x86_64.tar.g ...