剑指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 ...
随机推荐
- 解决“cv2.error: OpenCV(3.4.2) C:\projects\opencv-python\opencv\modules\highgui\src\window.cpp:356:...”
主要是图片路径中“文件夹分隔符”使用的错误 将“\”改成“/”就好了 修改后的测试代码如下:x.py #导入cv模块 import cv2 as cv #读取图像,支持 bmp.jpg.png.tif ...
- HTML标签---学习笔记
第一章 HTML标准结构学习: 顶层标签:html 投标签:head 主题标签:boby <html> <head> <meta charset="utf-8& ...
- codeforces#101194H. Great Cells(数学)
题目链接: https://codeforces.com/gym/101194 题意: 在$n×m$的各自中填上$1$到$k$的数 定义Greate cell为严格大于同行和同列的格子 定义$A_g$ ...
- 一个XP SP3调用0地址蓝屏BUG
0x00 蓝屏的堆栈 在XP SP3上跑POC之后,一段时间之后会出现蓝屏,蓝屏的堆栈如下,可以看出是ACKData里面CALL了一个0指针导致的蓝屏 0x01 蓝屏原因 1 ETW(Event Tr ...
- 安装mysql后必须要做的一件事
Step 1. 检查默认账户和密码 $cat /etc/mysql/debian.cnf # 在ubuntu下查看默认账户名和密码 会看到 [client] host = localhost user ...
- Dynatrace
1.概述 过去,企业的IT部门在测量系统性能时,一般重点测量为最终用户提供服务的硬件组件的利用率,如CPU利用率以及通过网络传输的字节数.虽然这种方法也提供了一些宝贵的信息,但却忽视了最重要的因素-- ...
- 打印Linq生成的SQL语句
var t1 = source.OrderBy<T>(orderby).Skip<T>(_skip).Take<T>(_take); var t2 = t1.ToO ...
- python md5验签
import hashlib #api验签 参数按首字母排序,然后拼接clientid=123456&num=xxxx&status=1×tamp=157319776 ...
- 分组卷积+squeezenet+mobilenet+shufflenet的参数及运算量计算
来一发普通的二维卷积 1.输入feature map的格式为:m * m * h1 2.卷积核为 k * k 3.输出feature map的格式为: n * n * h2 参数量:k * k * h ...
- 依赖管理系统 go modules
golang在1.11版本中引入了新的包管理工具 go mod 类似于maven包管理(多项目公用),而之前的vendor类似于node的node_modules管理(各个项目一份) 依赖信息添加到g ...