树
-
树的形状
-
普通二叉树、平衡二叉树、完全二叉树、二叉搜索树、四叉树(Quadtree)、多叉树(N-ary Tree)。
-
平衡二叉树:每一个节点的左右子树的高度差不超过1。
-
完全二叉树:除了最后一层,所有层的节点数达到最大,与此同时,最后一层的所有节点都在最左侧,堆使用完全二叉树。
-
满二叉树:所有层的节点数达到最大。
-
二分搜索树:每个节点的键值大于左孩子;每个节点的键值小于右孩子;以左右孩子为根的子树仍为二分搜索树。
-
基本操作:
- 插入insert
- 查找find
- 删除delete
-
主要考察知识点:
- 最大值,最小值minimum, maximum
- 前驱,后继successor, predecessor
- 上界,下界floor, ceil
- 某个元素的排名rank
- 寻找第k大(小)元素select
-
-
-
解题思路
- 迭代:循环判断,不断更新赋值
- 递归:先判断,再调用自身函数,迭代左右子树
-
经典例题:
-
LeetCode 第 235 题:二叉搜索树的最近公共祖先
-
LeetCode 第 98 题:验证二叉搜索树
-
LeetCode 第 450 题:删除二叉搜索树中的节点,考虑若删除的节点不存在?是否可能有多个需要删除的节点?删除的节点是否需要返回?
-
LeetCode 第 108 题:将有序数组转换为二叉搜索树
-
LeetCode 第 230 题:二叉搜索树中第K小的元素
-
LeetCode 第 236 题:二叉树的最近公共祖先
-
-
树的遍历
- 前序遍历(Preorder Traversal)
- 方法:先访问根节点,然后访问左子树,最后访问右子树。在访问左、右子树的时候,同样,先访问子树的根节点,再访问子树根节点的左子树和右子树,这是一个不断递归的过程。
- 应用场景:运用最多的场合包括在树里进行搜索以及创建一棵新的树。
- 中序遍历(Inorder Traversal)
- 方法:先访问左子树,然后访问根节点,最后访问右子树,在访问左、右子树的时候,同样,先访问子树的左边,再访问子树的根节点,最后再访问子树的右边。
- 应用场景:最常见的是二叉搜素树,由于二叉搜索树的性质就是左孩子小于根节点,根节点小于右孩子,对二叉搜索树进行中序遍历的时候,被访问到的节点大小是按顺序进行的。
- 后序遍历(Postorder Traversal)
- 方法:先访问左子树,然后访问右子树,最后访问根节点。
- 应用场景:在对某个节点进行分析的时候,需要来自左子树和右子树的信息。收集信息的操作是从树的底部不断地往上进行,好比你在修剪一棵树的叶子,修剪的方法是从外面不断地往根部将叶子一片片地修剪掉。
- 前序遍历(Preorder Traversal)
-
注意
- 大部分关于树的面试题都与递归有关,换句话说,面试官希望通过一道关于树的问题来考察你对于递归算法掌握的熟练程度。
- 掌握好这三种遍历的递归写法和非递归写法是非常重要的,懂得分析各种写法的时间复杂度和空间复杂度同样重要。
- 无论是前端工程师,还是后端工程师,在准备面试的时候,树这个数据结构都是最应该花时间学习的,既能证明你对递归有很好的认识,又能帮助你学习图论。树的许多性质都是面试的热门考点,尤其是二叉搜索树(BST)。
-
经典例题:
- LeetCode 第 104 题:二叉树的最大深度
- LeetCode 第 111 题:二叉树的最小深度
- LeetCode 第 226 题:翻转二叉树
- LeetCode 第 100 题:相同的树
- LeetCode 第 101 题:对称二叉树
- LeetCode 第 222 题:完全二叉树的节点个数
- LeetCode 第 110 题:平衡二叉树
- LeetCode 第 112 题:路径总和,注意递归的终止条件
- LeetCode 第 404 题:左叶子之和,注意递归的终止条件
- LeetCode 第 257 题:二叉树的所有路径
- LeetCode 第 113 题:路径总和 II
- LeetCode 第 129 题:求根到叶子节点数字之和
- LeetCode 第 437 题:路径总和 III