数据结构与算法

数据结构与算法知识详解
帅旋
关注
充电
IT宅站长,技术博主,架构师,全网id:arthinking。

平衡二叉搜索树数据结构

发布于 2020-04-28 | 更新于 2024-05-16

10、平衡二叉搜索树BBST

平衡二叉搜索树(Balanced Binary Search Tree BBST)是一种自平衡的二叉搜索树。所以自平衡意味着会自行调整,以保持较低(对数)的高度,从而允许更快的操作,例如插入和删除。

10.1、树旋转

大多数BBST算法核心组成部分是:树不变式树旋转的巧妙用法。

树不变式:是在每次操作后必须满足的属性/规则。为了确保始终满足不变式,通常会应用一系列树旋转

在树旋转的过程中需要确保保持BST的不变式:左子树比较小,右子树比较大。

10.1.1、更新单向指针的BBST

为此,我们可以使用以下操作实现右旋转,注意观察宣传前后,BST的不变式:

1
2
3
4
5
6
public void rightRotate(Node a) {
Node b = a.left;
a.left = b.right;
b.right = a;
return b;
}

如下图,我们准备执行rightRotate(a)

image-20200425151451455

为什么可以这样变换呢?

还是那个原则:BST不变式

所有BBST都是BST,因此对于每个节点n,都有:n.left <n && n < n.right。(这里的前提是没有重复元素)

我们在变换操作的时候只要确保这个条件成立即可,即保持BST不变性成立的前提下,我们可以对树中的值和节点进行随机变换/旋转。

注意,如上图,如果a节点还有父节点p,那么就把p节点原来指向a节点变更为指向b节点。

10.1.2、更新双向指针的BBST

在某些需要经常方位父节点或者同级节点的BBST中,我们就不是像上面那样最多更新3个指针,而是必须更新6个指针了,操作会复制些许。

以下是代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void rightRotate(Node a) {
Node p = a.parent
Node b = a.left;
a.left = b.right;
if (b.right != null) {
b.right.parent = a;
}
b.right = a;
a.parent = b;
b.parent = p;
// 更新父指针
if (p != null) {
if (p.left == a) {
p.left = b;
} else {
p.right = b;
}
}
return b;
}

image-20200425151505937

BBST通过在不满足其不变性时执行一系列左/右树旋转来保持平衡。

10.2、AVL树

AVL树是平衡二叉搜索树的一种,它允许以O(log(n))的复杂度进行插入、搜索和删除操作。

AVL树是第一种被发现的BBST,后来出现了其他类型包括: 2-3 tree、AA tree、scapegoat tree(替罪羊树)、red-black tree(红黑树)。

使AVL树保持平衡的属性称为平衡因子(balanced factor BF)。

BF(node) = H(node.right) - H(node.left)

其中H(x)是节点的高度,为x和最远的叶子之间的边数

AVL树中使其保持平衡的不变形是要求平衡因子BF始终为-1、0或者1。

10.2.1、节点存储信息

  • 节点存储的实际值,此值必须可以比较;

  • BF的值;

  • 节点在树中的高度;

  • 指向左右子节点的指针。

10.2.2、AVL的自平衡

当节点的BF不为-1、0或者1的时候,使用树旋转来进行调整。可以分为几种情况:

左左

image-20200425154109908

左右

image-20200425154944462

右右

image-20200425155139919

右左

image-20200425155553161

10.3、从BBST中移除元素

参考BST小节的删除逻辑,与之不同的是,在删除元素之后,需要执行多一个自平衡的过程。

10.4、时间复杂度

普通二叉搜索树:

操作 平均复杂度 最差复杂度
Insert O(log(n)) O(n)
Delete O(log(n)) O(n)
Remove O(log(n)) O(n)
Search O(log(n)) O(n)

平衡二叉搜索树:

操作 平均复杂度 最差复杂度
Insert O(log(n)) O(log(n))
Delete O(log(n)) O(log(n))
Remove O(log(n)) O(log(n))
Search O(log(n)) O(log(n))

10.5、编程实践

References

算法的时间与空间复杂度

Time and Space Complexity

Data Structures Easy to Advanced Course - Full Tutorial from a Google Engineer

本文作者: 帅旋

本文链接: https://www.itzhai.com/columns/dsa/bbst.html

版权声明: 版权归作者所有,未经许可不得转载,侵权必究!联系作者请加公众号。

×
IT宅

关注公众号及时获取网站内容更新。

请帅旋喝一杯咖啡

咖啡=电量,给帅旋充杯咖啡,他会满电写代码!

IT宅

关注公众号及时获取网站内容更新。