剑指offer:重建一个二叉树
时间:2022-07-22
本文章向大家介绍剑指offer:重建一个二叉树,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
作者 | 陌无崖
转载请联系授权
题目要求
根据前序遍历和中序遍历重建一个二叉树
//前序遍历
{1, 2, 4, 7, 3, 5, 6, 8}
//中序遍历
{4, 7, 2, 1, 5, 3, 8, 6}
解题思路
解答这个题之前,需要我们了解有关数据结构中二叉树树的相关知识,二叉树的结构如下图所示
其次我们还需要知道二叉树的前序遍历和中序遍历的特点,对于前序遍历,根节点一定是遍历之后的第一个结果,对于中序遍历,根节点一定是在中间,且根节点的左侧都是左子树,右侧都是右子树
知道了上面的性质仍然不够,我们还需要理解在树中递归的思想。
举一个例子,对于一个二叉树,当我们进行前序遍历的时候,我们的代码通常用递归的方式完成,让我们来具体看看这个递归
func preorder(root *Node) {
if root == nil {
return
}
fmt.Print(root.data)
preorder(root.left)
preorder(root.right)
}
在这个函数中,我们不停的递归我们的树的子树,将子树当成新的树进行递归输出,那么当我们构建的时候,我们根节点的左子树也可以不断的赋值我们的根节点根据我们输出的序列。知道这个思路我们就能很轻松的写出代码了,因为我们分别找到了左、右子树的前序遍历序列和中序遍历序列,我们就可以用同样的方法分别去构建左右子树。换句话说,这是一个递归的过程。
代码思路
1、根据前序遍历的性质找到我们的根节点
2、根据根节点和中序遍历的结果比较出该树的左子树部分和右子树部分
3、对每一个子树进行上述操作赋值根节点
完整代码
func contruct(pre []int, mid []int) (t *Node) {
l := len(pre)
if l == 0 {
return nil
}
root := &Node{
data: pre[0],
}
if l == 1 {
return root
}
leftlen, rightlen := 0, 0
// 遍历我们的中序遍历结果,找到位置分开左子树和右子树
for _, v := range mid {
if v == pre[0] {
break
}
leftlen++
}
rightlen = l - leftlen - 1
// 构建我们的左子树
if leftlen > 0 {
root.left = contruct(pre[1:leftlen+1], mid[0:leftlen])
}
if rightlen > 0 {
root.right = contruct(pre[leftlen+1:], mid[leftlen+1:])
}
return root
}
- 剑指offer代码解析——面试题21包含min函数的栈
- 剑指offer代码解析——面试题19二叉树的镜像
- mysql高可用架构设计,处理高并发,大流量!
- 零基础入门深度学习 | 第三章:神经网络和反向传播算法
- 微信企业付款到个人钱包引发的坑之反思~!
- Intellij idea创建javaWeb以及Servlet简单实现
- 设计模式之代理模式之读写分离!!!
- Phantomjs+Nodejs+Mysql数据抓取(1.数据抓取)
- Phantomjs+Nodejs+Mysql数据抓取(2.抓取图片)
- 深入浅出Redis-redis底层数据结构(上)
- Linux下自动化监控内存、存储空间!
- 深入浅出Redis-redis底层数据结构(下)
- Spring-boot:快速搭建微框架服务
- Mysql重要参数说明
- 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 数组属性和方法
- Spring的学习与实战(续)
- mycat数据库集群系列之数据库多实例安装
- 自已动手作图搞清楚AVL树
- 自己动手作图深入理解二叉树、满二叉树及完全二叉树
- AsyncTask记录
- spring cloud gateway跨域冲突功能的开发
- Spring同时集成JPA与Mybatis
- Qt音视频开发10-ffmpeg控制播放
- 拿好了!Linux 运维必备的 13 款实用工具!
- 自制CA证书设置ssl证书
- MySQL数据迁移TcaplusDB实践
- TKE之初识容器探测器
- 2.3.2 JDK动态代理 -《SSM深入解析与项目实战》
- mac设备安装nginx注意事项
- 《研发运营安全白皮书(2020年)》深度解读:全生命周期安全体系将是未来趋势