只吹理解不记忆,不如回家去种地:)
不要沉溺在“我看懂了”、“我理解了”、“我知道你说的是啥意思了”这种虚无的成就感中——假的,都是假的,只有自己写出来的代码才是真的!
二叉树的遍历
按照顺序规则:
- 先序遍历
- 中序遍历
- 后序遍历
- 层次遍历
按照实现方式:
- 递归遍历(先、中、后序遍历)
- 迭代遍历(层次遍历)
递归遍历
简单来说,一个函数反复调用自己的时候,递归就发生了;需要了解两个概念:
- 递归式 :每一次重复的内容是什么
- 递归边界 :指的是你什么时候停下来
最基本的二叉树结构:根结点,左子树,右子树
根据“根结点”的位置,那么遍历顺序可以有:
- 根结点 -> 左子树 -> 右子树 (先序遍历)
- 左子树 -> 根结点 -> 右子树 (中序遍历)
- 左子树 -> 右子树 -> 根结点 (后序遍历)
先序遍历
代码实现:
const root = {
val: "A",
left: {
val: "B",
left: {
val: "D"
},
right: {
val: "E"
}
},
right: {
val: "C",
right: {
val: "F"
}
}
};
// 所有遍历函数的入参都是树的根结点对象
function preorder(root) {
// 递归边界,root 为空
if (!root) {
return
}
// 输出当前遍历的结点值
console.log('当前遍历的结点值是:', root.val)
// 递归遍历左子树
preorder(root.left)
// 递归遍历右子树
preorder(root.right)
}
当前遍历的结点值是: A
当前遍历的结点值是: B
当前遍历的结点值是: D
当前遍历的结点值是: E
当前遍历的结点值是: C
当前遍历的结点值是: F
中序遍历
// 中序遍历
// 所有遍历函数的入参都是树的根结点对象
function inorder(root) {
// 递归边界,root 为空
if (!root) {
return
}
// 递归遍历左子树
inorder(root.left)
// 输出当前遍历的结点值
console.log('当前遍历的结点值是:', root.val)
// 递归遍历右子树
inorder(root.right)
}
当前遍历的结点值是: D
当前遍历的结点值是: B
当前遍历的结点值是: E
当前遍历的结点值是: A
当前遍历的结点值是: C
当前遍历的结点值是: F
后序遍历
function postorder(root) {
// 递归边界,root 为空
if (!root) {
return
}
// 递归遍历左子树
postorder(root.left)
// 递归遍历右子树
postorder(root.right)
// 输出当前遍历的结点值
console.log('当前遍历的结点值是:', root.val)
}
当前遍历的结点值是: D
当前遍历的结点值是: E
当前遍历的结点值是: B
当前遍历的结点值是: F
当前遍历的结点值是: C
当前遍历的结点值是: A
——————————————————————
(关于迭代遍历(层次遍历)真题中学习)