剑指offer代码解析——面试题19二叉树的镜像
时间:2022-05-03
本文章向大家介绍剑指offer代码解析——面试题19二叉树的镜像,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
分析:所谓“镜像”就是从镜子里看到的样子。我们可以画一棵二叉树,然后画出该二叉树的镜像。画完图之后我们会发现,所谓“二叉树的镜像”就是把二叉树中所有子树的左孩子和右孩子进行交换。因此需要遍历二叉树所有的结点,在遍历的同时交换非叶子结点的左右子树。遍历我们可以使用先序遍历,首先判断当前根结点是否为叶子结点,若非叶子结点,则交换左右孩子,然后再分别对左右孩子进行相同的操作。
首先,我们需要构造二叉树的结点类,一个结点中包含一个数据域data、一个左孩子left、一个右孩子right,代码如下:
/**
* 二叉树的结点
*/
class BinaryTreeNode<T>{
T data;//结点的数据域
BinaryTreeNode<T> left;//左子树
BinaryTreeNode<T> right;//右子树
}
下面开始编写镜像函数:
/**
* 二叉树镜像函数
* @param root 输入二叉树的根结点
*/
public static <T> void binaryTreeMirror(BinaryTreeNode<T> root){
//若二叉树为空
if(root==null)
return;
//若二叉树只有一个结点
if(root.left==null && root.right==null)
return;
//若二叉树为有孩子结点,则交换左右子树
{
//交换左右子树
BinaryTreeNode<T> temp = root.left;
root.left = root.right;
root.right = temp;
}
//分别对左右重复上述操作
{
if(root.left!=null)
binaryTreeMirror(root.left);
if(root.right!=null)
binaryTreeMirror(root.right);
}
}
为了能够对上述算法进行测试,我编写了一个二叉树的中序遍历函数,我们可以比较二叉树镜像前和镜像后的中序遍历结果来判断算法是否正确。二叉树中序遍历函数如下:
<span style="white-space:pre"> </span>/**
* 二叉树的中序遍历
* @param root 输入的二叉树的根
*/
public static <T> void preOrder(BinaryTreeNode<T> root){
//若当前二叉树为空
if(root==null)
return;
//中序遍历二叉树
{
preOrder(root.left);//中序遍历左子树
System.out.print(root.data+",");//访问根结点
preOrder(root.right);//中序遍历右子树
}
}
一切准备工作就绪,下面就开始测试我们的算法吧。
我创建了一棵四个结点的二叉树,并且所有结点均是左孩子。那么经过镜像后该二叉树的所有结点应该都是右孩子。并且前后两棵树的中序遍历正好是逆序关系。
public static void main(String[] args){
BinaryTreeNode<Integer> root = new BinaryTreeNode<Integer>();
BinaryTreeNode<Integer> root1 = new BinaryTreeNode<Integer>();
BinaryTreeNode<Integer> root2 = new BinaryTreeNode<Integer>();
BinaryTreeNode<Integer> root3 = new BinaryTreeNode<Integer>();
root.data = 0;
root1.data = 1;
root2.data = 2;
root3.data = 3;
root.left = root1;
root1.left = root2;
root2.left = root3;
System.out.println("镜像前:");
preOrder(root);
System.out.println("镜像后:");
binaryTreeMirror(root);
preOrder(root);
}
输出结果为:
镜像前:3,2,1,0
镜像后:0,1,2,3
- Enumerable#zip特性
- java小技术之生成二维码
- java实现发送邮件服务器,SMTP协议发送邮件
- HttpURLConnection实现两个服务端的对接
- java获取properties配置文件值
- 安全退出app,activoty栈管理
- JavaBean转Map方法
- JsBridge实现JavaScript和Java的互相调用
- JAVA-FTP批量大文件传输
- 独家 | 一文读懂TensorFlow(附代码、学习资料)
- 解决openssh漏洞,升级openssh版本
- 解决NTPD漏洞,升级Ntpd版本
- 独家 | 手把手教TensorFlow(附代码)
- HBase Region自动切分细节
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- SpringBoot2 整合Ehcache组件,轻量级缓存管理
- 数据源管理 | 分布式NoSQL系统,Cassandra集群管理
- 【NPM库】- 0x03 - Express
- 数值微分|多项式的导数计算
- 让windows 10 内置ubuntu(WSL)成为扩增子分析生产力
- 手把手教你自定义Spring Boot Starter
- 高职考技能提升教程013期 冒泡排序法和选择排序法
- python带你剪辑视频
- python自制有声小说
- CVE-2017-8570及利用样本分析
- “既生 ExecutorService, 何生 CompletionService?”
- XXE -XML External Entity
- Vivado时序收敛技术(一) Baseline基础理论
- ShardingJdbc分库分表实战案例解析(上)
- ShaderDesigner:OpenGL shader调试神器