那么接下来,我们就来介绍一下二叉树吧。
二叉树的概念
二叉树是一种典型的树树状结构。如它名字所描述的那样,二叉树是每个节点最多有两个子树的树结构,通常子树被称作“左子树”和“右子树”。
图片来自网络,具体出处不明。
从这个图片的内容来看,应该很清楚的展示了二叉树的结构。
至于二叉树的性质的话,可以参考下图,作为补充知识吧,个人觉得这个不是重点。
重点的话,我们需要掌握的应该是它的遍历方式。
二叉树的遍历
我们知道对于二叉树的遍历而言,有常见得三种遍历方式,分别是以下三种:
- 前序遍历
- 中序遍历
- 后序遍历
对于任何一种遍历方式而言,我们不仅需要掌握它的非递归版本,同时对于它的递归版本来说,更是考察一个人的算法基本功,那么接下来,我们来看看吧。
前序遍历
练习二叉树的前序遍历
给你二叉树的根节点 root
,返回它节点值的 前序 遍历。
假设我们mock一下假数据👇
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,3,2]
那么根据我们对前序遍历的理解,我们可以写出解题伪代码👇
// TianTianUp
// * function TreeNode(val, left, right) {
// * this.val = (val===undefined ? 0 : val)
// * this.left = (left===undefined ? null : left)
// * this.right = (right===undefined ? null : right)
// * }
let preorderTraversal = (root, arr = []) => {
if(root) {
arr.push(root.val)
preorderTraversal(root.left, arr)
preorderTraversal(root.right, arr)
}
return arr
}
非递归版本👇
对于非递归的话,我们需要借助一个数据结构去存储它的节点,需要使用的就是栈,它的思路可以借鉴👇
- 根节点为目标节点,开始向它子节点遍历
- 1.访问目标节点
- 2.左孩子入栈 -> 直至左孩子为空的节点
- 3.节点出栈,以右孩子为目标节点,再依次执行1、2、3
let preorderTraversal = (root, arr = []) => {
const stack = [], res = []
let current = root
while(current || stack.length > 0) {
while (current) {
res.push(current.val)
stack.push(current)
current = current.left
}
current = stack.pop()
current = current.right
}
return res
}
中序遍历
给定一个二叉树,返回它的中序 遍历。
示例:
输入: [1,null,2,3] 1
2 / 3输出: [1,3,2]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
来源:力扣(LeetCode)著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
递归版本👇
const inorderTraversal = (root, arr = []) => {
if(root) {
inorderTraversal(root.left, arr)
arr.push(root.val)
inorderTraversal(root.right, arr)
}
return arr
}
非递归版本,这里就不解释了,跟前序遍历一样,思路一样,用栈维护节点信息。
const inorderTraversal = (root, arr = []) => {
const stack = [], res = []
let current = root
while(current || stack.length > 0) {
while (current) {
stack.push(current)
current = current.left
}
current = stack.pop()
res.push(current.val)
current = current.right
}
return res
}
后续遍历
给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3]
1
2 / 3输出: [3,2,1]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
来源:力扣(LeetCode)著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
递归版本👇
const postorderTraversal = (root, arr = []) => {
if(root) {
postorderTraversal(root.left, arr)
postorderTraversal(root.right, arr)
arr.push(root.val)
}
return arr
}
非递归版本👇
其实,嗯,做完前面两个后,会发现都是有套路滴~
const postorderTraversal = (root, arr = []) => {
const stack = [], res = []
let current = root, last = null // last指针记录上一个节点
while(current || stack.length > 0) {
while (current) {
stack.push(current)
current = current.left
}
current = stack[stack.length - 1]
if (!current.right || current.right == last) {
current = stack.pop()
res.push(current.val)
last = current
current = null // 继续弹栈
} else {
current = current.right
}
}
return res
}
二叉树的层次遍历 ⭐⭐
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
学习分享,共勉
这里是小编拿到的学习资源,其中包括“中高级Java开发面试高频考点题笔记300道.pdf”和“Java核心知识体系笔记.pdf”文件分享,内容丰富,囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。同时还有Java进阶学习的知识笔记脑图(内含大量学习笔记)!
资料都是免费提供的,整理不易,有需要的朋友可以转发分享下,同时可以关注我,定期分享学习资源还会更新一些技术分享!
整理不易,有需要的朋友转发支持下,感谢感谢!
Java核心知识体系笔记.pdf
中高级Java开发面试高频考点题笔记300道.pdf
架构进阶面试专题及架构学习笔记脑图
Java架构进阶学习视频分享
…(img-KLFuzYNx-1628619652188)]
中高级Java开发面试高频考点题笔记300道.pdf
[外链图片转存中…(img-E8LOcgf2-1628619652191)]
架构进阶面试专题及架构学习笔记脑图
[外链图片转存中…(img-Uc8aI5g6-1628619652193)]
Java架构进阶学习视频分享
[外链图片转存中…(img-T4TpsXYA-1628619652194)]