>

>
1x
go to beginning previous frame pause play next frame go to end
二叉搜索树(又:二叉查找树,二叉排序树,Binary Search Tree,BST)是一种二叉树,其中每个结点最多有两个子结点且具有二叉搜索树性质:左子树上所有结点的值均小于它的根结点的值以及右子树上所有结点的值均大于它的根结点的值(在这个可视化中,我们假定所有的值都是独特的。如有重复的值,则需要略作调整。)试试 Search(7),它会用动画展示如何在上面的随机 BST 中找到一个 ∈ [1..99] 的随机数。

自平衡二叉查找树(AVL 树)是带了自平衡功能的二叉查找树。当结点树为N时,它能够使高度平衡为 O(log N)。

Remarks: By default, we show e-Lecture Mode for first time (or non logged-in) visitor.
If you are an NUS student and a repeat visitor, please login.

🕑

要在标准二叉搜索树和AVL树之间切换(只有在插入和删除整数期间有不同的行为),请选择相应的标题。

此URL也能帮助你快速访问AVL树模式,即https://visualgo.net/zh/avl 。你可以将en改成其他语言(zh, id)。


Pro-tip 1: Since you are not logged-in, you may be a first time visitor (or not an NUS student) who are not aware of the following keyboard shortcuts to navigate this e-Lecture mode: [PageDown]/[PageUp] to go to the next/previous slide, respectively, (and if the drop-down box is highlighted, you can also use [→ or ↓/← or ↑] to do the same),and [Esc] to toggle between this e-Lecture mode and exploration mode.

🕑

BST(尤其是像AVL Tree这样平衡的BST)是实现某种(或映射)抽象数据类型(ADT)的高效数据结构。

表ADT必须至少支持以下三种操作:

  1. 搜索(v) - 确定 ADT 中是否存在 v,
  2. 插入(v) - 将 v 插入ADT,
  3. 删除(v) - 从 ADT 中删除 v 。

参考:请参阅哈希表e-Lecture中的类似幻灯片


Pro-tip 2: We designed this visualization and this e-Lecture mode to look good on 1366x768 resolution or larger (typical modern laptop resolution in 2021). We recommend using Google Chrome to access VisuAlgo. Go to full screen mode (F11) to enjoy this setup. However, you can use zoom-in (Ctrl +) or zoom-out (Ctrl -) to calibrate this.

🕑
我们指的是键值需要有序的表格(Table) ADT(而不是键值无需有序的表ADT)。
表格ADT的特殊要求将在接下来的几张幻灯片中更加清晰。

Pro-tip 3: Other than using the typical media UI at the bottom of the page, you can also control the animation playback using keyboard shortcuts (in Exploration Mode): Spacebar to play/pause/replay the animation, / to step the animation backwards/forwards, respectively, and -/+ to decrease/increase the animation speed, respectively.

🕑
如果我们使用未排序的数组(array)/向量(vector)来实现表ADT,它可能效率低下:
  1. 搜索(v)在O(N)中运行,因为如果v实际上不存在,我们最终可能会探索ADT的所有N个元素,
  2. 插入(v)可以在O(1)中实现,只需将v放在数组的后面,
  3. 删除(v)也在O(N)中运行,因为我们必须首先搜索已经O(N)的v,然后用 O(N) 时间删除后处理被删除元素的空位。
🕑
如果我们使用排序的数组/向量来实现表ADT,我们可以提高搜索(v)性能,但会削弱插入(v)性能:
  1. 搜索(v)现在可以在O(log N),中实现,因为我们现在可以在已排序的数组上使用二进制搜索,
  2. 插入(v)现在在O(N)中运行,因为我们需要实现类似插入的策略以使数组保持排序状态,
  3. 删除(v)在O(N)中运行,因为即使 Search(v) O(log N)中运行,我们仍然需要在删除后关闭间隙 - 在O(N)中。
🕑

此e-Lecture的目标是引入BST和平衡BST(AVL树)数据结构,以便我们可以在远小于 N 的 O(log N) 时间内实现基本的表ADT操作:搜索(v),插入(v),删除(v)和一些 其他Table ADT操作 - 参见下一张幻灯片。
PS:一些经验丰富的读者可能会注意到存在另一种数据结构可以在更快的时间内实现三种基本的表ADT操作,但请继续阅读......

N≈ 1 000≈ 1 000 000≈ 1 000 000 000
log N10Only 20 :OOnly 30 :O:O
🕑
除了基本的三个之外,还有一些其他可能的表ADT操作:
  1. 找到 Min()/ Max() 元素,
  2. 找到 Successor(v) - '下一个更大' / Predecessor(v) - '上一个更小'元素,
  3. 按排序顺序列出元素,
  4. X&Y操作 - 因 NUS 教学目的被隐藏
  5. 还有其他可能的操作。
讨论:如果我们仅限于使用[sorted | unsorted] array / vector,此处前三个操作的最佳实现是什么?
🕑

The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various flipped classrooms in NUS.


If you are really a CS lecturer (or an IT teacher) (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (show your University staff profile/relevant proof to Steven) for Steven to manually activate this CS lecturer-only feature for you.


FAQ: This feature will NOT be given to anyone else who is not a CS lecturer.

🕑

可用于实现表ADT的更简单的数据结构是链接列表

Quiz: Can we perform all basic three Table ADT operations: Search(v)/Insert(v)/Remove(v) efficiently (read: faster than O(N)) using Linked List?

Yes
No

讨论:为什么?

🕑

The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various flipped classrooms in NUS.


If you are really a CS lecturer (or an IT teacher) (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (show your University staff profile/relevant proof to Steven) for Steven to manually activate this CS lecturer-only feature for you.


FAQ: This feature will NOT be given to anyone else who is not a CS lecturer.

🕑

可用于实现表ADT的另一种数据结构是哈希表。 它具有非常快的搜索(v),插入(v)和删除(v)性能(所有都在预期的O(1时间内)。

Quiz: So what is the point of learning this BST module if Hash Table can do the crucial Table ADT operations in unlikely-to-be-beaten expected O(1) time?

There is no point, so this BST module can be ignored
There are valid reasons, which are ____

讨论上面的答案! 提示:回到之前的4张幻灯片。

🕑

The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various flipped classrooms in NUS.


If you are really a CS lecturer (or an IT teacher) (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (show your University staff profile/relevant proof to Steven) for Steven to manually activate this CS lecturer-only feature for you.


FAQ: This feature will NOT be given to anyone else who is not a CS lecturer.

🕑
我们现在将介绍BST数据结构。 查看上面BST示例的可视化!
根顶点没有父节点。 BST中只能有一个根顶点。 叶顶点没有任何子节点。 BST中可以有多个叶顶点。 非叶子的顶点称为内部顶点。 有时根顶点不包含在内部顶点定义内,因为只有一个顶点的BST的根也符合叶子的定义。
在上面的例子中,顶点15是根顶点,顶点{5,7,50}是叶子,顶点{4,6,15(也是根),23,71}是内部顶点。
🕑
每个顶点至少有4个属性:父,左,右,键/值/数据(还有其他潜在的属性)。 并非所有属性都将用于所有顶点,例如 根顶点的父属性为NULL。 一些其他实现将键(用于BST中的顶点的排序)和与键相关联的实际卫星数据分开。
顶点(叶子除外)的左/右子节点分别绘制在该顶点的左/右下方。 顶点的父节点(根除外)绘制在该顶点上方。 每个顶点的(整数)键在表示该顶点的圆内绘制。 在上面的例子中,(键)15的左子为6,右子为23。 因此,6(和23)的父母是15。
🕑
由于我们在此可视化中不允许重复整数,因此 BST 有如下特性:对于每个顶点X,X的左子树上的所有顶点都一定小于X,并且右子树X上的所有顶点都一定大于X。
在上面的示例中,根15的左子树上的顶点:{4,5,6,7} 都小于15,根15的右子树上的顶点:{23,50,71} 全部大于15。您也可以递归地检查其他顶点上来验证二叉树的这个特性。
若要更完整的实现,我们也应该考虑重复的整数。最简单的方法是在每个顶点上多加一个属性:X出现的频率。(该可视化会在近期添加)
🕑

We provide visualization for the following common BST/AVL Tree operations:

  1. Query operations (the BST structure remains unchanged):
    1. Search(v),
    2. Predecessor(v) (and similarly Successor(v)), and
    3. Inorder/Preorder Traversal (we will add Postorder Traversal soon),
  2. Update operations (the BST structure may likely change):
    1. Insert(v),
    2. Remove(v), and
    3. Create BST (several criteria).
🕑

还有一些其他BST(查询)操作尚未在VisuAlgo中可视化:

  1. Rank(v):给定键值 v,确定BST元素的排序顺序中的排名(基于1的索引)。 也就是说,Rank(FindMin()) = 1 且 Rank(FindMax()) = N。如果 v 不存在,我们报告 -1。
  2. Select(k):给定等级k,1 ≤ kN,确定在BST中具有该等级k的键值 v。 换句话说,找到BST中的第k小的元素,也就是 Select(1) = FindMin() and Select(N) = FindMax()。

因为一门 NUS 的课程需要用到这两种操作的细节,它们被隐藏起来了。

🕑
只有在没有(或罕见)更新时才高效的数据结构,尤其是插入和/或删除操作,称为静态数据结构。
即使存在许多更新操作,也高效的数据结构也称为动态数据结构。 BST,尤其是平衡的BST(例如AVL树)就属于这一类。
🕑

Because of the way data (distinct integers for this visualization) is organised inside a BST, we can binary search for an integer v efficiently (hence the name of Binary Search Tree).


First, we set the current vertex = root and then check if the current vertex is smaller/equal/larger than integer v that we are searching for. We then go to the right subtree/stop/go the left subtree, respectively. We keep doing this until we either find the required vertex or we don't.


On the example BST above, try clicking Search(23) (found after 2 comparisons), Search(7) (found after 3 comparisons), Search(21) (not found after 2 comparisons — at this point we will realize that we cannot find 21).

🕑

Similarly, because of the way data is organised inside a BST, we can find the minimum/maximum element (an integer in this visualization) by starting from root and keep going to the left/right subtree, respectively.


Try clicking FindMin() and FindMax() on the example BST shown above. The answers should be 4 and 71 (both after comparing against 3 integers from root to leftmost vertex/rightmost vertex, respectively).

🕑
Search(v)/ FindMin() / FindMax() 操作在 O(h) 中运行,其中 h 是 BST 的高度。
但请注意,在普通的 BST 中这个 h 可能和 O(N) 一样高,如上面随机的“向右倾斜”示例所示。 尝试 Search(100)(这个值不应该存在,因为我们只使用 [1..99] 之间的随机整数生成这个随机 BST,因此搜索例程应该用 O(N) 时间检查从根到唯一的叶子 — 效率很低。
🕑
由于BST属性,我们可以找到整数 v 的后继(假设我们通过之前调用 Search(v) 已经知道整数 v 的位置),如下所示:
  1. 如果 v 具有右子树,则 v 的右子树中的最小整数必须是 v 的后继。尝试Successor(23)(应为50)。
  2. 如果 v 没有右子树,我们需要遍历 v 的祖先,直到我们找到'右转'到顶点 w(或者,直到我们发现第一个大于顶点 v 的顶点 w)。 一旦我们找到顶点 w,我们将看到顶点 v w 的左子树中的最大元素。 试试Successor(7)(应该是15)。
  3. 如果 v 是BST中的最大整数,则 v 没有后继。 试试Successor(71)(应该没有)。
🕑
整数v的前驱的操作类似地定义(只是后继操作的镜像)。
尝试相同的三个镜像的极端情况:Predecessor(6)(应为5),Predecessor(50)(应为23),Predecessor(4)(应为无/none)。
此时,请暂停一会并思考这三个后继(v)/ 前驱(v)案例,以确保您理解这些概念。
🕑
前驱(v)和后继(v)操作在 O(h) 中运行,其中h是BST的高度。
但请记住,这个h可以和正常BST中的 O(N) 一样高,如上面的随机“倾斜右侧”示例所示。 如果我们调用Successor(FindMax()),我们将在 O(N) 时间从最后一个叶子回到根 - 效率不高。
🕑
我们可以执行这个BST的Inorder Traversal(中序遍历)来获得这个BST中的排序整数列表(事实上,如果我们将BST压平成一行,我们将看到顶点是从最小/最左边到最大/最右边来排序的)。

中序遍历是一种递归方法,我们首先访问左子树,遍历左子树中的所有项,访问当前子树的根,然后浏览右子树和右子树中的所有项。 不用多说了,让我们尝试Inorder Traversal,看看它在上面的BST示例中如何操作。
🕑

无论BST的高度如何,Inorder Traversal都以O(N)运行。
讨论:为什么?
PS:有些人调用N个无序整数插入O(N log N)中的BST,然后执行O(N)Inorder Traversal作为'BST sort'。 它很少使用,因为有几种比这更容易使用(基于比较)的排序算法

🕑

The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various flipped classrooms in NUS.


If you are really a CS lecturer (or an IT teacher) (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (show your University staff profile/relevant proof to Steven) for Steven to manually activate this CS lecturer-only feature for you.


FAQ: This feature will NOT be given to anyone else who is not a CS lecturer.

🕑

We have included the animation for Preorder but we have not do the same for Postorder tree traversal method.


Basically, in Preorder Traversal, we visit the current root before going to left subtree and then right subtree. For the example BST shown in the background, we have: {{15}, {6, 4, 5, 7}, {23, 71, 50}}. PS: Do you notice the recursive pattern? root, members of left subtree of root, members of right subtree of root.


In Postorder Traversal, we visit the left subtree and right subtree first, before visiting the current root. For the example BST shown in the background, we have: {{5, 4, 7, 6}, {50, 71, 23}, {15}}.

🕑
我们可以通过执行与Search(v)类似的操作将新整数插入到BST中。 但这一次,我们不是报告找不到新的整数,而是在插入点中创建一个新的顶点并将新的整数放在那里。 在上面的示例中尝试Insert(60)
🕑
插入(v)在O(h)中运行,其中h是BST的高度。
到目前为止你应该知道这个 h 在正常BST中可以和 O(N) 一样高,如上面随机的“向右倾斜”示例所示。 如果我们调用Insert(FindMax()+1),即我们插入一个大于当前最大值的新整数,我们将在O(N)时间内从根向下移动到最后一个叶子,然后插入新整数作为最后一个叶子的右子节点 - 效率不高(请注意,在此可视化中我们最多只允许h=9)。
🕑

Quiz: Inserting integers [1,10,2,9,3,8,4,7,5,6] one by one in that order into an initially empty BST will result in a BST of height:

The height cannot be determined
8
10
9

专业提示:您可以使用“探索模式”来验证答案。
🕑
我们可以通过执行与 Search(v) 类似的操作来删除BST中的整数。
如果在BST中找不到 v,我们什么都不做。
如果在BST中找到 v,我们不会报告找到了整数v,而是执行三个可能的删除案例中的一个,这些案例将在三个单独的幻灯片中详细说明(我们建议您一个一个的尝试每个幻灯片)。
🕑
第一种情况是最简单的:顶点v当前是BST的叶顶点之一。
删除叶子顶点很容易:我们只删除那个叶子顶点 - 在上面的示例BST上尝试Remove(5)(第一次删除后第二次点击将无效 - 请刷新此页面或转到另一张幻灯片并返回到此幻灯片 )。
这部分显然是O(1) - 在早期的O(h)搜索类的努力之上。
🕑
第二种情况也不是那么难:Vertex v是BST的一个(内部/根)顶点,它只有一个子节点。 删除v而不执行任何其他操作将断开BST。
删除带有一个子节点的顶点并不难:我们将该顶点的唯一子节点与该顶点的父节点连接 - 在上面的示例BST上尝试Remove(23)(在第一次删除后第二次点击将无效 - 请刷新此页面或转到另一张幻灯片并返回此幻灯片)。
这部分也显然是O(1) - 在早期的O(h)搜索类的努力之上。
🕑

第三种情况是三者中最复杂的:顶点v是BST的(内部/根)顶点,它只有两个子节点。 删除v而不执行任何其他操作将断开BST。

删除具有两个子节点的顶点如下:我们用它的后继替换该顶点,然后在其右子树中删除其重复的后继 - 在上面的示例BST上尝试Remove(6)(第一次删除后第二次点击将不执行任何操作) - 请刷新此页面或转到另一张幻灯片,然后返回此幻灯片)。

这部分需要O(h),因为在之前的O(h)类似搜索的努力之外还需要找到后继顶点 。

🕑

本案例3值得进一步讨论:

  1. 为什么用后继C替换有两个子节点的顶点B总是一个有效的策略?
  2. 我们可以用它的前身A替换有两个子节点的顶点B吗? 为什么或者为什么不?
🕑

The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various flipped classrooms in NUS.


If you are really a CS lecturer (or an IT teacher) (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (show your University staff profile/relevant proof to Steven) for Steven to manually activate this CS lecturer-only feature for you.


FAQ: This feature will NOT be given to anyone else who is not a CS lecturer.

🕑
移除v,即 remove(v),需要 O(h) 时间运行,其中h是BST的高度。 删除案例3(删除带有两个子节点的顶点是“最重的”,但不超过O(h))。
正如你现在应该完全理解的那样,h可以和正常BST中的 O(N) 一样高,如上面随机的“向右倾斜”示例所示。 如果我们调用Remove(FindMax()),即我们删除当前的最大整数,我们将在删除它之前要用 O(N) 时间从根向下直到最后一个叶子 — 这样效率很低。
🕑

To make life easier in 'Exploration Mode', you can create a new BST using these options:

  1. Empty BST (you can then insert a few integers one by one),
  2. The two e-Lecture Examples that you may have seen several times so far,
  3. Random BST (which is unlikely to be extremely tall),
  4. Skewed Left/Right BST (tall BST with N vertices and N-1 linked-list like edges, to showcase the worst case behavior of BST operations; disabled in AVL Tree mode).
🕑

BST的解读已经过半了。 到目前为止,我们注意到许多基本的表格ADT操作在 O(h) 中运行,而 h 可以像 N-1 条边一样高,就像所示的“向左倾斜”一样 - 效率低下:( ...
那么,有没有办法让我们的BST“不那么高”?


PS:如果你想研究如何在真实程序中实现这些基本的BST操作,你可以下载这个BSTDemo.cpp

🕑

此时,我们建议您按 [Esc] 或单击此e-Lecture幻灯片右下角的X按钮进入“探索模式”并自行尝试各种BST操作,以加强您对这种多功能数据结构的理解。
当您准备继续阅读平衡BST(以AVL树为示例)时,再次按 [Esc] 或从右上角的下拉菜单中将模式切换回“电子演讲模式”。 然后,使用幻灯片选择器下拉列表this slide 12-1恢复。

🕑
我们从之前的幻灯片中看到,除了中序遍历之外,我们的大部分BST操作都在 O(h) 中运行,其中h是BST的高度,可以与 N-1 一样高。
我们将继续讨论平衡BST的概念,以使得 h = O(log N)。
🕑
有几种已知的平衡BST的实现,但是太多了不能在VisuAlgo中逐一可视化和解释。
我们专注于AVL Tree(Adelson-Velskii&Landis,1962),以其发明者Adelson-Velskii和Landis命名。
其他平衡的BST实现(或多或少好于常数因子c)是:红黑树,B树/ 2-3-4树(Bayer&McCreight,1972),Splay树(Sleator 和Tarjan,1985),Skip Lists(Pugh,1989),Treaps( Seidel和Aragon,1996)等。
🕑
为了促进AVL Tree的实现,我们需要增加 - 为每个BST顶点添加更多信息/属性。
对于每个顶点v,我们定义height(v):从顶点v到其最深叶子的路径上的边数。 此属性保存在每个顶点中,因此我们可以在O(1)中访问顶点的高度,而无需每次都重新计算它。
🕑

正式公式是:

v.height = -1 (if v is an empty tree)
v.height = max(v.left.height, v.right.height) + 1 (otherwise)
因此,BST的高度是: root.height

在上面的例子BST上, height(11) = height(32) = height(50) = height(72) = height(99) = 0 (所有都是叶子)。height(29) = 1,因为有1个边将它连接到它唯一的叶子32上。

🕑

Quiz: What are the values of height(20), height(65), and height(41) on the BST above?

height(20) = 2
height(65) = 2
height(41) = 4
height(20) = 3
height(41) = 3
height(65) = 3
🕑

如果我们在BST中有N个元素/项/键,假如我们能以某种方式以完美的顺序插入N个元素,以便BST完全平衡的话,则下限高度 h > log2 N

请参阅上面显示的 N = 15 的示例(在现实生活中很难实现的完美BST - 尝试插入任何其他整数,它将不再完美)。

🕑
N ≤ 1 + 2 + 4 + ... + 2h
N ≤ 20 + 21 + 22 + … + 2h
N < 2h+1 (几何级数之和)
log2 N < log2 2h+1
log2 N < (h+1) * log2 2 (log2 2 is 1)
h > (log2 N)-1 (代数操作)
h > log2 N
🕑
如果我们在BST中有N个元素/项目/键,那么如果我们按升序插入元素,则上限高度 h < N(如上所示,右倾BST)。
这种BST的高度是 h = N-1,所以我们有
 h < N.
讨论:您知道如何左倾BST吗?

🕑

The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various flipped classrooms in NUS.


If you are really a CS lecturer (or an IT teacher) (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (show your University staff profile/relevant proof to Steven) for Steven to manually activate this CS lecturer-only feature for you.


FAQ: This feature will NOT be given to anyone else who is not a CS lecturer.

🕑
我们已经看到大多数BST操作需要 O(h) 时间,并且结合h的下限和上限后会得到 log2 N < h < N
log2 N N 之间存在显着差异,我们从下限的讨论中看到,总是获得完美BST几乎不可能......
那么,对于一个小的常数因子c,我们可以得到高度接近 log2 N 的BST,即高度c * log2 N 的 BST 吗? 如果可以,那么需要O(h)运行的BST操作实际上只需 O(log N) 运行...

🕑
介绍AVL Tree,其早在1962年由两位俄罗斯(苏联)发明家 Georgy Adelson-Velskii和Evgenii Landis 发明。
在AVL树中,我们稍后会看到它的高度 h < 2 * log N(有更严谨的分析,但我们将在VisuAlgo中使用 c = 2 情况下的较简单的分析)。 因此,大多数AVL Tree操作以 O(log N) 时间高效运行。
插入(v)和删除(v)更新操作可能会更改AVL树的高度 h,但我们将看到旋转操作以保持较低的 AVL 树高度。
🕑
为了提高效率,每次有更新 (Insert(v)/Remove(v)) 操作时,我们都不会通过 O(N) 递归方法维护 height(v) 属性。
相反,我们在 Insert(v)/Remove(v) 操作的后面计算 O(1) 的:x.height = max(x.left.height, x.right.height) + 1,因为只有沿插入/移除路径的顶点的高度 (height) 可能会受到影响。 因此,只有 O(h) 顶点可以改变其 height(v) 属性,并且在AVL树中,h <2 * log N.
在示例AVL树上尝试Insert(37)(暂时忽略生成的旋转,我们将在接下来的几张幻灯片中回到它)。 请注意,沿插入路径只有几个顶点:{41,20,29,32}将高度增加+1,所有其他顶点的高度不变。
🕑
让我们定义以下重要的AVL树不变式(永不改变的属性):如果|v.left.height - v.right.height| ≤ 1,则顶点 v 被称为高度平衡
如果BST中的每个顶点都是高度平衡的,则根据上面的不变式此BST被称为高度平衡。 这样的BST称为AVL Tree,就像上面的例子一样。
在这里暂停一会,并尝试插入一些新的随机顶点或删除一些随机存在的顶点。 生成的BST是否仍然被认为是高度平衡的?
🕑
Adelson-Velskii 和 Landis 声称具有N个顶点的AVL树(满足AVL树不变式的高度平衡BST)具有高度 h < 2 * log2N
证明依赖于高度为 h 的最小 AVL 树。
令 Nh 为高度为h的AVL树中的最小顶点数。
Nh的前几个值是N0 = 1(单个根顶点),N1 = 2(只有一个左子或一个右子的根顶点),N2 = 4,N3 = 7,N4 = 12,N5 = 20(见背景图片),等等(见下两张幻灯片)。
🕑

我们知道,对于 N 个顶点的任何其他AVL树(不一定是最小尺寸的),N ≥ Nh

Proof-2

在背景图片中,我们有N5 = 20个顶点,但我们知道在我们有一个高度为h = 5的完美二叉树之前,我们可以再挤进43个顶点(最多N = 63)。

🕑
Nh = 1 + Nh-1 + Nh-2 (高度为h的最小尺寸AVL树的公式)
Nh > 1 + 2*Nh-2 (Nh-1 > Nh-2)
Nh > 2*Nh-2 (obviously)
Nh > 4*Nh-4 (递归)
Nh > 8*Nh-6 (另一个递归步骤)
... (假设初始h是偶数,我们只能这样做h/2次)
Nh > 2h/2*N0 (我们到了base case)
Nh > 2h/2 (N0 = 1)
Proof-3
🕑
N ≥ Nh > 2h/2 (结合前两张幻灯片)
N > 2h/2
log2(N) > log2(2h/2) (两边都是log2)
log2(N) > h/2 (等式化简)
2 * log2(N) > h 或 h < 2 * log2(N)
h = O(log(N)) (最后结论)
Proof-4
🕑

再看一下BST示例。 看到所有顶点都是高度平衡的AVL树。
为了快速检测顶点v是否高度平衡,我们将AVL树的(内部具有绝对函数的)不变式修改为:bf(v) = |v.left.height - v.right.height|
现在再次在AVL树上尝试Insert(37)。 插入路径上的几个顶点:{41,20,29,32}的高度增加1。 在插入之后顶点{29,20}将不再高度平衡了(并且将在稍后旋转 - 在接下来的几张幻灯片中讨论),i.e. bf(29)= -2和bf(20)= -2。 我们需要恢复平衡。

🕑
Tree Rotation

见上图。 在左侧图片上调用rotateRight(Q) 将生成正确的图片。 在右图上调用rotateLeft(P)将再次产生左图。
只有当T有一个左/右子节点时,才能调用rotateRight(T)/rotateLeft(T) 
Tree Rotation保留BST属性。 在旋转之前,P ≤ B ≤ Q。旋转之后,请注意以B为根的子树(如果存在)的父节点改变了,但 P ≤ B ≤ Q 不会更改。

🕑
BSTVertex rotateLeft(BSTVertex T) // 先决条件:T的右子节点 T.right != null
BSTVertex w = T.right // 右旋是这个的镜像
w.parent = T.parent // 这个方法新手很难写对
T.parent = w
T.right = w.left
if (w.left != null) w.left.parent = T
w.left = T
// 更新 T 和 w 的高度 height
return w
🕑
Four Cases

基本上,只有这四种不平衡的情况。 我们使用Tree Rotation(树旋转)来处理它们中的每一个。

🕑
  1. 只需像普通BST一样插入v,
  2. 从插入点向上走AVL树回到根。每走一步,我们更新受影响顶点的高度和平衡因子:
    1. 如果有的话,停止在不平衡的第一个顶点(+2或-2),
    2. 使用四个树旋转案例中的一个来重新平衡它,例如 在上面的例子上尝试Insert(37)并通过调用 rotateLeft(29) 解决不平衡问题。

讨论:AVL Tree的 Insert(v) 操作是否还有其他树旋转情况?

🕑

The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various flipped classrooms in NUS.


If you are really a CS lecturer (or an IT teacher) (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (show your University staff profile/relevant proof to Steven) for Steven to manually activate this CS lecturer-only feature for you.


FAQ: This feature will NOT be given to anyone else who is not a CS lecturer.

🕑
  1. 只需删除正常BST中的v(三个删除案例中的一个),
  2. 在AVL树种从删除点向上走回根节点,每一步,我们都会更新受影响的顶点的高度和平衡因子:
    1. 现在,对于每个不平衡的顶点(+2或-2),我们使用四个树旋转情况中的一个来重新平衡它们(可能多于一个)。

与AVL树中的 Insert(v) 相比的主要区别在于,我们可能会多次触发四种可能的重新平衡情况中的一种,但不会超过 h = O(log N) 次 :O。在上面的示例中尝试Remove(7),能看到连锁反应rotateRight(6) 然后rotateRight(16) + rotateLeft(8)

🕑

我们现在看到AVL Tree如何定义高度平衡不变式,在 Insert(v) 和 Remove(v) 操作期间保持其对所有顶点成立,以及AVL Tree具有h <2 * log N的证明。
因此,到目前为止我们学到的所有BST操作(除了Inorder Traversal之外的更新和查询操作),如果它们具有 O(h) 的时间复杂度,如果我们使用AVL 树版本,它们的时间复杂度为 O(log N)。
本节电子讲座到这里就结束了,但是请切换到“探索模式”并尝试在AVL树模式下对Insert(v)和Remove(v)进行各种调用,以加强您对此数据结构的理解。


PS:如果你想研究这些看似复杂的AVL树(旋转)操作是如何在真实程序中实现的,你可以下载这个AVLDemo.cpp(必须与这个BSTDemo.cpp一起使用)。

🕑
在这个模块的结尾,我们将讨论一些关于BST和平衡BST(尤其是AVL树)的有趣事情。
🕑

The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various flipped classrooms in NUS.


If you are really a CS lecturer (or an IT teacher) (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (show your University staff profile/relevant proof to Steven) for Steven to manually activate this CS lecturer-only feature for you.


FAQ: This feature will NOT be given to anyone else who is not a CS lecturer.

🕑

The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various flipped classrooms in NUS.


If you are really a CS lecturer (or an IT teacher) (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (show your University staff profile/relevant proof to Steven) for Steven to manually activate this CS lecturer-only feature for you.


FAQ: This feature will NOT be given to anyone else who is not a CS lecturer.

🕑

有关此数据结构的一些有趣的问题,请在BST/AVL训练模块上练习(无需登录)。
但是,对于注册用户,您应该登录然后转到主培训页面以正式清除此模块,此类成就将记录在您的用户帐户中。

🕑

我们还有一些编程问题需要使用这种平衡的BST(如AVL Tree)数据结构:Kattis - compoundwordsKattis - baconeggsandspam
尝试使用它们来巩固和提高您对此数据结构的理解。 如果这样可以简化您的实现,则可以使用C ++ STL map / set或Java TreeMap / TreeSet。

尝试使用它们来巩固和提高您对此数据结构的理解。你可以使用 C++ STL map/set,Java TreeMap/TreeSet,或 OCaml Map/Set 来简化您的实现。请注意 Python 没有内置的平衡 BST 的实现。

🕑

The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various flipped classrooms in NUS.


If you are really a CS lecturer (or an IT teacher) (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (show your University staff profile/relevant proof to Steven) for Steven to manually activate this CS lecturer-only feature for you.


FAQ: This feature will NOT be given to anyone else who is not a CS lecturer.


You have reached the last slide. Return to 'Exploration Mode' to start exploring!

Note that if you notice any bug in this visualization or if you want to request for a new visualization feature, do not hesitate to drop an email to the project leader: Dr Steven Halim via his email address: stevenhalim at gmail dot com.

🕑

Visualisation Scale

创建

插入

移除

前驱/后继

Tree Traversal

>

1.0x (Default)

0.5x (Minimal Details)

清空

Unbalanced Example

Balanced Example

随机

Random Large

向左偏斜

向右偏斜

v =

执行

v =

执行

v =

找前驱

找后继

Inorder

Preorder

Postorder

We use cookies to improve our website.
By clicking ACCEPT, you agree to our use of Google Analytics for analysing user behaviour and improving user experience as described in our Privacy Policy.
By clicking reject, only cookies necessary for site functions will be used.

ACCEPT REJECT
关于 团队 使用条款 隐私政策

关于

VisuAlgo于2011年由Steven Halim博士创建,是一个允许学生以自己的速度自学基础知识,从而更好地学习数据结构与算法的工具。
VisuAlgo包含许多高级算法,这些算法在Steven Halim博士的书(“Competitive Programming”,与他的兄弟Felix Halim博士合作)和其他书中有讨论。今天,一些高级算法的可视化/动画只能在VisuAlgo中找到。
虽然本网站是专门为新加坡国立大学(NUS)学生学习各种数据结构和算法类(例如CS1010,CS2040,CS3230,CS3233,CS4234)而设,但我们作为在线学习的倡导者,我们非常希望世界各地的好奇的头脑能发现这些非常有用的算法可视化。
VisuAlgo不是从一开始就设计为在小触摸屏(例如智能手机)上工作良好,因为为了满足许多复杂算法可视化,需要大量的像素和点击并拖动手势进行交互。为得到良好的用户体验,最低屏幕分辨率应为1024x768,并且本网站只有首页相对适合移动设备。但是,我们正在测试一个准备在2022年4月发布的移动版本。
VisuAlgo是一个正在进行的项目,更复杂的可视化仍在开发中。
最令人兴奋的发展是自动问题生成器和验证器(在线测验系统),允许学生测试他们的基本数据结构和算法的知识。这些问题是通过一些随机生成的规则,学生的答案会在提交给我们的评分服务器后立即自动分级。这个在线测验系统,当它被更多的世界各地的CS教师采用,应该能从技术上消除许多大学的典型计算机科学考试手动基本数据结构和算法问题。通过在通过在线测验时设置小(但非零)的重量,CS教练可以(显着地)增加他/她的学生掌握这些基本问题,因为学生具有几乎无限数量的可以立即被验证的训练问题他们参加在线测验。培训模式目前包含12个可视化模块的问题。我们将很快添加剩余的12个可视化模块,以便VisuAlgo中的每个可视化模块都有在线测验组件。
VisuAlgo支持三种语言:英语,中文,印尼语。目前,我们还以各种语言写了有关VisuAlgo的公共注释:
id, kr, vn, th.

团队

项目领导和顾问(2011年7月至今)
Dr Steven Halim, Senior Lecturer, School of Computing (SoC), National University of Singapore (NUS)
Dr Felix Halim, Senior Software Engineer, Google (Mountain View)

本科生研究人员 1 (Jul 2011-Apr 2012)
Koh Zi Chun, Victor Loh Bo Huai

最后一年项目/ UROP学生 1 (Jul 2012-Dec 2013)
Phan Thi Quynh Trang, Peter Phandi, Albert Millardo Tjindradinata, Nguyen Hoang Duy

最后一年项目/ UROP学生 2 (Jun 2013-Apr 2014)
Rose Marie Tan Zhao Yun, Ivan Reinaldo

本科生研究人员 2 (May 2014-Jul 2014)
Jonathan Irvin Gunawan, Nathan Azaria, Ian Leow Tze Wei, Nguyen Viet Dung, Nguyen Khac Tung, Steven Kester Yuwono, Cao Shengze, Mohan Jishnu

最后一年项目/ UROP学生 3 (Jun 2014-Apr 2015)
Erin Teo Yi Ling, Wang Zi

最后一年项目/ UROP学生 4 (Jun 2016-Dec 2017)
Truong Ngoc Khanh, John Kevin Tjahjadi, Gabriella Michelle, Muhammad Rais Fathin Mudzakir

最后一年项目/ UROP学生 5 (Aug 2021-Dec 2022)
Liu Guangyuan, Manas Vegi, Sha Long, Vuong Hoang Long

最后一年项目/ UROP学生 6 (Aug 2022-Apr 2023)
Lim Dewen Aloysius, Ting Xiao

List of translators who have contributed ≥100 translations can be found at statistics page.

致谢
本项目运营资金是由NUS教学与学习发展中心(CDTL)的教学增进款慷慨提供的。

使用条款

VisuAlgo is free of charge for Computer Science community on earth. If you like VisuAlgo, the only "payment" that we ask of you is for you to tell the existence of VisuAlgo to other Computer Science students/instructors that you know =) via Facebook/Twitter/Instagram/TikTok posts, course webpages, blog reviews, emails, etc.

If you are a data structure and algorithm student/instructor, you are allowed to use this website directly for your classes. If you take screen shots (videos) from this website, you can use the screen shots (videos) elsewhere as long as you cite the URL of this website (https://visualgo.net) and/or list of publications below as reference. However, you are NOT allowed to download VisuAlgo (client-side) files and host it on your own website as it is plagiarism. As of now, we do NOT allow other people to fork this project and create variants of VisuAlgo. Using the offline copy of (client-side) VisuAlgo for your personal usage is fine.

Note that VisuAlgo's online quiz component is by nature has heavy server-side component and there is no easy way to save the server-side scripts and databases locally. Currently, the general public can only use the 'training mode' to access these online quiz system. Currently the 'test mode' is a more controlled environment for using these randomly generated questions and automatic verification for real examinations in NUS.

List of Publications

This work has been presented briefly at the CLI Workshop at the ICPC World Finals 2012 (Poland, Warsaw) and at the IOI Conference at IOI 2012 (Sirmione-Montichiari, Italy). You can click this link to read our 2012 paper about this system (it was not yet called VisuAlgo back in 2012) and this link for the short update in 2015 (to link VisuAlgo name with the previous project).

This work is done mostly by my past students. 

Bug Reports or Request for New Features

VisuAlgo is not a finished project. Dr Steven Halim is still actively improving VisuAlgo. If you are using VisuAlgo and spot a bug in any of our visualization page/online quiz tool or if you want to request for new features, please contact Dr Steven Halim. His contact is the concatenation of his name and add gmail dot com.

隐私政策

Version 1.1 (Updated Fri, 14 Jan 2022).

Disclosure to all visitors: We currently use Google Analytics to get an overview understanding of our site visitors. We now give option for user to Accept or Reject this tracker.

Since Wed, 22 Dec 2021, only National University of Singapore (NUS) staffs/students and approved CS lecturers outside of NUS who have written a request to Steven can login to VisuAlgo, anyone else in the world will have to use VisuAlgo as an anonymous user that is not really trackable other than what are tracked by Google Analytics.

For NUS students enrolled in modules that uses VisuAlgo: By using a VisuAlgo account (a tuple of NUS official email address, NUS official student name as in the class roster, and a password that is encrypted on the server side — no other personal data is stored), you are giving a consent for your module lecturer to keep track of your e-lecture slides reading and online quiz training progresses that is needed to run the module smoothly. Your VisuAlgo account will also be needed for taking NUS official VisuAlgo Online Quizzes and thus passing your account credentials to another person to do the Online Quiz on your behalf constitutes an academic offense. Your user account will be purged after the conclusion of the module unless you choose to keep your account (OPT-IN). Access to the full VisuAlgo database (with encrypted passwords) is limited to Steven himself.

For other NUS students, you can self-register a VisuAlgo account by yourself (OPT-IN).

For other CS lecturers worldwide who have written to Steven, a VisuAlgo account (your (non-NUS) email address, you can use any display name, and encrypted password) is needed to distinguish your online credential versus the rest of the world. Your account will be tracked similarly as a normal NUS student account above but it will have CS lecturer specific features, namely the ability to see the hidden slides that contain (interesting) answers to the questions presented in the preceding slides before the hidden slides. You can also access Hard setting of the VisuAlgo Online Quizzes. You can freely use the material to enhance your data structures and algorithm classes. Note that there can be other CS lecturer specific features in the future.

For anyone with VisuAlgo account, you can remove your own account by yourself should you wish to no longer be associated with VisuAlgo tool.