平衡二叉搜索树
Contents
平衡二叉搜索树 (BBST)
二叉搜索树(BST)的缺陷?
二叉搜索树,在某种情况下会导致极度的不平衡,导致时间复杂度剧增。
如图,如果按照 7 4 9 2 5 8 11 的顺序添加节点
如果按照从小到大的顺序添加节点
二叉树退化成链表
如何改进BST?
有没有办法防止二叉搜索树退化成链表?
让添加,删除,搜索的复杂度维持在 O(log N)
平衡
平衡:当节点数量固定时,左右子树的高度越来越接近,这棵二叉树就越平衡(高度越低).
理想平衡
最理想的平衡,就是像完全二叉树,满二叉树那样,高度是最小的。
改进
- 首先,节点的添加,删除顺序是无法限制的,可以认为是随机的
- 所以改进的方案是,在节点添加,删除操作之后,想办法让二叉搜索树恢复平衡(减小树的高度)
- 如果接着继续调整节点的位置,完全可以达到理想平衡,但是付出的代价可能会比较大
- 比如调整的次数会比较多,反而增加了时间复杂度
- 总结来说,比较合理的改进方案是:用尽量少的调整次数达到适度的平衡即可。
- 一棵达到适度平衡的二叉搜索树,可以称之为平衡二叉搜索树。
平衡二叉搜索树 (Balanced Binary Search Tree)
- 英文简称为: BBST
- 经典常见的平衡二叉搜索树
- AVL树 (Windows NT内核广泛应用)
- 红黑树
- C++ STL (map , set)
- Java中的TreeMap, TreeSet, HashMap, HashSet
- Linux的进程调度
- Ngix 的 timer 管理
- 一般也称它们为: 自平衡的二叉搜索树(Self-balancing Binary Search Tree)
练习题
110. 平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]
3 /
9 20 /
15 7 返回 true 。示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
1
/
2 2 /
3 3 /
4 4 返回 false 。来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/balanced-binary-tree 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解:
思路一:
平衡二叉树的概念是,每个节点左右子树的高度相差的绝对值 <= 1 。 故思路很简单,我们遍历二叉树每个节点,并计算其左右子树高度差绝对值,所有都 <=1, 则平衡,其中有绝对值 > 1的,则不平衡。
代码如下:
|
|
计算节点高度有两种方法
-
递归, 节点的高度等于其左右子树的高度中的最大值 + 1
-
迭代, 利用层序遍历,遍历完一层,height++。 直至遍历完所有节点
上述方法是自顶向下的递归,越深处的子节点,需要经过更多次数的计算,包含大量重复的计算。 下边方法中,我们用自下而上的递归,减少重复计算。
可以递归计算当前节点子节点的高度,然后根据子节点的高度判断当前节点是否平衡。
思路二:
从底至顶
思路是对二叉树前序遍历,从底至顶返回子树的最大高度,若判断某子树不是平衡二叉树则 “剪枝”,直接向上返回。
算法流程:
|
|
-
递归返回值
- 当节点 root 左右子树的高度差 < 2,则返回以节点root为根节点的子树的最大高度,即节点root的左右子树中最大高度 + 1
- 当节点root 左右子树高度差 >= 2, 则代表root不平衡,直接返回 -1.
-
递归终止条件
- 叶子节点时,返回高度0
- 当左(右)子树高度left == -1时,则代表此子树的 左(右)子树 不是平衡树, 因此直接返回 -1.
1
isBalance(root):
- 返回值:若recur(root) != -1, 则代表是平衡二叉树。
代码如下:
|
|
Author 飞熊
LastMod May 11