剑指offer18:操作给定的二叉树,将其变换为源二叉树的镜像。
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:操作给定的二叉树,将其变换为源二叉树的镜像。的更多相关文章
- 剑指Offer-18.二叉树的镜像(C++/Java)
题目: 题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ ...
- 二叉树的镜像(剑指offer-18)
题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 解析 先前序遍历这棵树的每个结点,如果遍历到的结点有子结点,就交换它的两个子节点, 当交换完所有的非叶子结点的左右子结点之后,就得到了树的镜像 ...
- C++版 - 剑指offer 面试题23:从上往下打印二叉树(二叉树的层次遍历BFS) 题解
剑指offer 面试题23:从上往下打印二叉树 参与人数:4853 时间限制:1秒 空间限制:32768K 提交网址: http://www.nowcoder.com/practice/7fe2 ...
- 【javascript】操作给定的二叉树,将其变换为源二叉树的镜像。
操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ 11 9 ...
- 剑指Offer的学习笔记(C#篇)-- 平衡二叉树(二叉树后序遍历递归详解版)
题目描述 输入一棵二叉树,判断该二叉树是否是平衡二叉树. 一 . 题目分析 首先要理解一个概念:什么是平衡二叉树,如果某二叉树中任意的左右子树深度相差不超过1,那么他就是一颗平衡二叉树.如下图: 所以 ...
- 剑指OFFER18 判断一个二叉树的子树
public class a18_IsSubTree { public static boolean hasSubTree(TreeNode treeRoot1, TreeNode treeRoot2 ...
- 剑指Offer面试题:21.从上到下打印二叉树
一.题目:从上到下打印二叉树 题目:从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印.例如输入下图中的二叉树,则依次打印出8.6.10.5.7.9.11. 二叉树节点的定义如下,采用 ...
- 剑指offer面试题23:从上到下打印二叉树(树的层序遍历)
题目:从上往下打印出二叉树的每个节点,同一层的结点按照从左往右的顺序打印. 解题思路:二叉树的层序遍历,在打印一个节点的时候,要把他的子节点保存起来打印第一层要把第二层的节点保存起来, 打印第二层要把 ...
- 剑指offer-字符的所有组合,复制复杂链表,二叉树中和为某一值的路径
字符的所有组合 描述: 输入一个字符串,求这个字符串中的字符的所有组合.如:"abc",组合为"a" "b" c" "a ...
随机推荐
- Java分布式互联网架构/微服务/高性能/springboot/springcloud2018年10月16日直播内容
2018年10月16日直播内容 架构师揭秘springboot对springmvc的自动配置原理 直播地址:https://ke.qq.com/course/179440?tuin=9b386640 ...
- MGR---mysql组复制多主模式
组复制有两种模式:单主模式和多主模式. 1.在单主模式下,组复制具有自动选主功能,每次只有一个 server成员接受更新.2.在多主模式下,所有的 server 成员都可以同时接受更新. MGR的限制 ...
- springboot+mybatis+druid+sqlite/mysql/oracle
搭建springboot+mybatis+druid+sqlite/mysql/oracle附带测试 1.版本 springboot2.1.6 jdk1.8 2.最简springboot环境 http ...
- 微信小程序开发-踩坑
异步请求处理 详情描述: 微信小程序的wx.request({})请求时异步处理,以下代码 wx.reuest({ url:"https://XXXA", method:" ...
- Ryu控制器编程开发——packet_in和packet_out简易交换机实现
Ryu控制器二次开发,实现一个简单的只能够简单地广播数据包的交换机. from ryu.base import app_manager from ryu.controller import ofp_e ...
- 能不能支持在线查看word,excel这样的文件?还有拖拽上传功能?
https://forum.enhancer.io/topic/5adea0cdce69735af635fcd8 方法1. 用一个自定义窗口, 自定义窗口里放一个iframe 假设你的 word 的地 ...
- puppeteer学习笔记合集
官方英文版API入口(如果你英文好的话):https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md. 汉化版API入口(网上有 ...
- debian、ubuntu安装metasploit通用方法
网上有很多方法让去github上下载安装,这方法的确可以但是特别慢,更新也特别慢,这里写下比较快的方法 1.添加kali源 vim /etc/apt/sources.list 在原有源的基础上添加国内 ...
- Airbnb架构要点分享——阅读心得
目前,Airbnb已经使用了大约5000个AWS EC2实例,其中大约1500个实例用于部署其应用程序中面向Web的部分,其余的3500个实例用于各种分析和机器学习算法.而且,随着Airbnb的发展, ...
- Linux中查看系统资源占用情况的命令
用 'top -i' 看看有多少进程处于 Running 状态,可能系统存在内存或 I/O 瓶颈,用 free 看看系统内存使用情况,swap 是否被占用很多,用 iostat 看看 I/O 负载情况 ...