🤔 树与递归
📚 树
为什么有树这个数据结构?假设递归求斐波那契数列f(n) = f(n-1) + f(n-2)
,如果把整个计算过程展开,你会发现这是一棵树。像 html,dom 节点展开后是一棵树。
如果树是无序的,查找元素是O(n)
如果树是有序的(二叉搜索树),查找元素是O(logn)
,类似于二分查找。假设一棵树所有结点都只有右节点,它就退化成链表,查询时间复杂度退化为O(n)
二叉搜索树
- 左子树的所有节点小于根节点
- 右子树的所有节点大于根节点
- 左右子树也是二叉搜索树
二叉树的遍历方式
- 前序遍历:根节点 -> 左子树 -> 右子树
- 中序遍历:左子树 -> 根节点 -> 右子树
- 后序遍历:左子树 -> 右子树 -> 根节点
节点定义
1 | function TreeNode(val) { |
🏫 二叉树的遍历 - 代码模板
树的解题方法一般都是递归,因为每个节点的结构相同,当你想访问左节点时,最好的方式是对左节点再调用一遍函数。
- 前序遍历
1 | const preorder = (node) => { |
- 中序遍历
1 | const inorder = (node) => { |
- 后序遍历
1 | const backorder = (node) => { |
🌲 递归与树
在函数体里调用函数本身,称为递归。把递归的全过程剥开,你会发现它是一个树结构。
1 | // 斐波那契 |
🏫 经典题目
105. 从前序与中序遍历序列构造二叉树
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
preorder = [3,9,2,1,7]
inorder = [9,3,1,2,7]
输出:[3,9,2,null,null,1,7]1
2
3
4
5 3
/ \
9 2
/ \
1 7
preorder [3,9,2,1,7] 根节点,左子树,右子树
[3 - 根节点, 9 - 左子树的preorder, 2,1,7 - 右子树的preorder]
inorder [9,3,1,2,7] 左子树,根节点,右子树
[9 - 左子树的inorder, 3 - 根节点, 1,2,7 - 右子树的inorder]
1 | var buildTree = function (preorder, inorder) { |