7    VisuAlgo.net / /bst Login 二叉搜索树
自平衡二叉查找树(AVL 树)
示例模式 ▿

>

>
减速
加速
go to beginning previous frame pause play next frame go to end

A Binary Search Tree (BST) is a binary tree in which each vertex has only up to 2 children that satisfies BST property: All vertices in the left subtree of a vertex must hold a value smaller than its own and all vertices in the right subtree of a vertex must hold a value larger than its own (we have assumption that all values are distinct integers in this visualization and small tweak is needed to cater for duplicates/non integer). Try clicking Search(7) for a sample animation on searching a random value ∈ [1..99] in the random BST above.


An Adelson-Velskii Landis (AVL) tree is a self-balancing BST that maintains it's height to be O(log N) when having N vertices in the AVL tree.


Click 'Next' (on the top right)/press 'Page Down' to advance this e-Lecture slide, use the drop down list/press 'Space' to jump to a specific slide, or Click 'X' (on the bottom right)/press 'Esc' to go to Exploration mode.


Remarks: By default, we show e-Lecture Mode for first time (or non logged-in) visitor.
Please login if you are a repeated visitor or register for an (optional) free account first.

X Esc
下一个 PgDn

To toggle between the standard Binary Search Tree and the AVL Tree (only different behavior during Insertion and Removal of an Integer), select the respective header.


We also have URL shortcut to quickly access the AVL Tree mode, which is https://visualgo.net/en/avl (you can change the 'en' to your two characters preferred language - if available).


Pro-tip: Since you are not logged-in, you may be a first time visitor who are not aware of the following keyboard shortcuts to navigate this e-Lecture mode: [PageDown] to advance to the next slide, [PageUp] to go back to the previous slide, [Esc] to toggle between this e-Lecture mode and exploration mode.

X Esc
上一个 PgUp
下一个 PgDn

BST (and especially balanced BST like AVL Tree) is an efficient data structure to implement a certain kind of Table (or Map) Abstract Data Type (ADT).


A Table ADT must support at least the following three operations as efficient as possible:

  1. Search(v) — determine if v exists in the ADT or not,
  2. Insert(v) — insert v into the ADT,
  3. Remove(v) — remove v from the ADT.

Reference: See similar slide in Hash Table e-Lecture.


Another pro-tip: We designed this visualization and this e-Lecture mode to look good on 1366x768 resolution or larger (typical modern laptop resolution in 2017). 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.

X Esc
上一个 PgUp
下一个 PgDn
我们指的是表格(Table)ADT,其中需要对键进行排序(与表ADT相反,其中键不需要是无序的)。
表格ADT的这一特殊要求将在接下来的几张幻灯片中更加清晰。
X Esc
上一个 PgUp
下一个 PgDn
如果我们使用未排序的数组/向量来实现表ADT,它可能效率低下:
  1. 搜索(v)在O(N)中运行,因为如果v实际上不存在,我们最终可能会探索ADT的所有N个元素,
  2. 插入(v)可以在O(1)中实现,只需将v放在数组的后面,
  3. 删除(v)也在O(N)中运行,因为我们必须首先搜索已经O(N)的v,然后在删除后关闭产生的间隙 - 也在O(N)中。
X Esc
上一个 PgUp
下一个 PgDn
如果我们使用排序的数组/向量来实现表ADT,我们可以提高搜索(v)性能,但会削弱插入(v)性能:
  1. 搜索(v)现在可以在O(log N),中实现,因为我们现在可以在已排序的数组上使用二进制搜索,
  2. 插入(v)现在在O(N)中运行,因为我们需要实现类似插入的策略以使数组保持排序状态,
  3. 删除(v)在O(N)中运行,因为即使 Search(v) O(log N)中运行,我们仍然需要在删除后关闭间隙 - 在O(N)中。
X Esc
上一个 PgUp
下一个 PgDn

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


N≈ 1 000≈ 1 000 000≈ 1 000 000 000
log N10Only 20 :OOnly 30 :O:O
X Esc
上一个 PgUp
下一个 PgDn

On top of the basic three, there are a few other possible Table ADT operations:

  1. Find the Min()/Max() element,
  2. Find the Successor(v) — 'next larger'/Predecessor(v) — 'previous smaller' element,
  3. List elements in sorted order,
  4. Operation X & Y - hidden for pedagogical purpose in an NUS module,
  5. There are others possible operations.

Discussion: What are the best possible implementation for the first three additional operations if we are limited to use [sorted|unsorted] array/vector?

X Esc
上一个 PgUp
下一个 PgDn

e-Lecture: The content of this slide is hidden and only available for legitimate CS lecturer worldwide. Drop an email to visualgo.info at gmail dot com if you want to activate this CS lecturer-only feature and you are really a CS lecturer (show your University staff profile).

X Esc
上一个 PgUp
下一个 PgDn

可用于实现表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?

No
Yes

讨论:为什么?

X Esc
上一个 PgUp
下一个 PgDn

e-Lecture: The content of this slide is hidden and only available for legitimate CS lecturer worldwide. Drop an email to visualgo.info at gmail dot com if you want to activate this CS lecturer-only feature and you are really a CS lecturer (show your University staff profile).

X Esc
上一个 PgUp
下一个 PgDn

可用于实现表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 are valid reasons, which are ____
There is no point, so this BST module can be ignored

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

X Esc
上一个 PgUp
下一个 PgDn

e-Lecture: The content of this slide is hidden and only available for legitimate CS lecturer worldwide. Drop an email to visualgo.info at gmail dot com if you want to activate this CS lecturer-only feature and you are really a CS lecturer (show your University staff profile).

X Esc
上一个 PgUp
下一个 PgDn

We will now introduce BST data structure. See the visualization of an example BST above!


Root vertex does not have a parent. There can only be one root vertex in a BST. Leaf vertex does not have any child. There can be more than one leaf vertex in a BST. Vertices that are not leaf are called the internal vertices. Sometimes root vertex is not included as part of the definition of internal vertex as the root of a BST with only one vertex can actually fit into the definition of a leaf too.


In the example above, vertex 15 is the root vertex, vertex {5, 7, 50} are the leaves, vertex {4, 6, 15 (also the root), 23, 71} are the internal vertices.

X Esc
上一个 PgUp
下一个 PgDn
每个顶点至少有4个属性:父,左,右,键/值/数据(还有其他潜在的属性)。 并非所有属性都将用于所有顶点,例如 根顶点的父属性为NULL。 一些其他实现将键(用于BST中的顶点的排序)和与键相关联的实际卫星数据分开。
顶点(叶子除外)的左/右子节点分别绘制在该顶点的左/右下方。 顶点的父节点(根除外)绘制在该顶点上方。 每个顶点的(整数)键在表示该顶点的圆内绘制。 在上面的例子中,(键)15的左子为6,右子为23。 因此,6(和23)的父母是15。
X Esc
上一个 PgUp
下一个 PgDn
由于我们在此可视化中不允许重复整数,因此BST属性如下所示:对于每个顶点X,X的左子树上的所有顶点都严格小于X,并且右子树X上的所有顶点都严格大于X。
在上面的示例中,根15的左子树上的顶点:{4,5,6,7}都小于15,根15的右子树上的顶点:{23,50,71}是 全部大于15.您也可以递归检查其他顶点上的BST属性。
为了更完整的实现,我们也应该考虑重复的整数,并且我们必须始终将等于X的整数放在一个子树上(不是任意的)。
X Esc
上一个 PgUp
下一个 PgDn
我们为以下常见的BST / AVL树操作提供可视化:
  1. .查询操作(BST结构保持不变):
1. 搜索(v)
2. 前身(v)(和类似的继承人(v)),和
3. Inorder Traversal(我们将很快添加Preorder和Postorder Traversal),
2. 更新操作(BST结构可能会改变):
1.插入(v)
2.删除(v),
3.创建BST(几个标准)。
X Esc
上一个 PgUp
下一个 PgDn

There are a few other BST (Query) operations that have not been visualized in VisuAlgo:

  1. Rank(v): Given a key v, determine what is its rank (1-based index) in the sorted order of the BST elements. That is, Rank(FindMin()) = 1 and Rank(FindMax()) = N. If v does not exist, we can report -1.
  2. Select(k): Given a rank k, 1 ≤ kN, determine the key v that has that rank k in the BST. Or in another word, find the k-th smallest element in the BST. That is, Select(1) = FindMin() and Select(N) = FindMax().

The details of these two operations are currently hidden for pedagogical purpose in a certain NUS module.

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

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(15) (found after just 1 comparison), Search(7) (found after 3 comparisons), Search(21) (not found after 3 comparisons).

X Esc
上一个 PgUp
下一个 PgDn
类似地,由于数据在BST内的组织方式,我们可以从root开始找到最小/最大元素(此可视化中的整数),并分别继续向左/右子树寻找。
尝试点击上面显示的示例BST上的FindMin()FindMax()。 答案应该是4和71(均在4次比较后)。
X Esc
上一个 PgUp
下一个 PgDn
Search(v)/ FindMin()/ FindMax()操作在O(h)中运行,其中h是BST的高度。
但请注意,这个h可以和普通BST中的O(N)一样高,如上面随机的“向右倾斜”示例所示。 尝试Search(100)(这个值不应该存在,因为我们只使用[1..99]之间的随机整数生成这个随机BST,因此搜索例程应该检查从根到O(N)时间内唯一的叶子 - 没有效率。
X Esc
上一个 PgUp
下一个 PgDn
由于BST属性,我们可以找到整数 v 的后继(假设我们已经知道整数 v 在早期的 Search(v)调用中的位置),如下所示:
  1. 如果 v 具有右子树,则 v 的右子树中的最小整数必须是 v 的后继。尝试Successor(23)(应为50)。
  2. 如果 v 没有右子树,我们需要遍历 v 的祖先,直到我们找到'右转'到顶点 w(或者,直到我们发现第一个顶点 w 大于顶点 v)。 一旦我们找到顶点 w,我们将看到顶点 v w 的左子树中的最大元素。 试试Successor(7)(应该是15)。
  3. 如果 v 是BST中的最大整数,则 v 没有后继。 试试Successor(71)(应该没有)。
X Esc
上一个 PgUp
下一个 PgDn
整数v的前驱的操作类似地定义(只是后继操作的镜像)。
尝试相同的三个角落(但镜像):Predecessor(6)(应为5),Predecessor(50)(应为23),Predecessor(4)(应为无)。
此时,请暂停一会并思考这三个后继(v)/ 前驱(v)案例,以确保您理解这些概念。
X Esc
上一个 PgUp
下一个 PgDn
前驱(v)和后继(v)操作在O(h)中运行,其中h是BST的高度。
但请记住,这个h可以和正常BST中的O(N)一样高,如上面的随机“倾斜右侧”示例所示。 如果我们调用Successor(FindMax()),我们将在O(N)时间从最后一个叶子回到根目录 - 效率不高。
X Esc
上一个 PgUp
下一个 PgDn

We can perform an Inorder Traversal of this BST to obtain a list of sorted integers inside this BST (in fact, if we 'flatten' the BST into one line, we will see that the vertices are ordered from smallest/leftmost to largest/rightmost).


Inorder Traversal is a recursive method whereby we visit the left subtree first, exhausts all items in the left subtree, visit the current root, before exploring the right subtree and all items in the right subtree. Without further ado, let's try Inorder Traversal to see it in action on the example BST above.

X Esc
上一个 PgUp
下一个 PgDn

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

X Esc
上一个 PgUp
下一个 PgDn

e-Lecture: The content of this slide is hidden and only available for legitimate CS lecturer worldwide. Drop an email to visualgo.info at gmail dot com if you want to activate this CS lecturer-only feature and you are really a CS lecturer (show your University staff profile).

X Esc
上一个 PgUp
下一个 PgDn
我们还没有包含这两种其他经典树遍历方法的动画,但我们很快就会这样做。
但基本上,在Preorder Traversal中,我们在转到左子树然后右子树之前访问当前根。 对于后台显示的示例BST,我们有:{{15},{6,4,5,7},{23,71,50}}。 PS:你注意到了递归模式吗? root,root的左子树成员,root的右子树成员。
在Postorder Traversal中,我们在访问当前根之前首先访问左子树和右子树。 对于后台显示的示例BST,我们有:{{5,4,7,6},{50,71,23},{15}}。
X Esc
上一个 PgUp
下一个 PgDn

We can insert a new integer into BST by doing similar operation as Search(v). But this time, instead of reporting that the new integer is not found, we create a new vertex in the insertion point and put the new integer there. Try Insert(60) on the example above.

X Esc
上一个 PgUp
下一个 PgDn
插入(v)在O(h)中运行,其中h是BST的高度。
到目前为止你应该知道这个h可以和正常BST中的O(N)一样高,如上面随机的“向右倾斜”示例所示。 如果我们调用Insert(FindMax()+1),即我们插入一个大于当前最大值的新整数,我们将从根向下移动到最后一个叶子,然后在O(N)时间内插入新整数作为最后一个叶子的右子节点 - 效率不高(请注意,在此可视化中我们只允许h = 9)。
X Esc
上一个 PgUp
下一个 PgDn

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
10
9
8

专业提示:您可以使用“探索模式”来验证答案。
X Esc
上一个 PgUp
下一个 PgDn
我们可以通过执行与 Search(v) 类似的操作来删除BST中的整数。
如果在BST中找不到 v,我们什么都不做。
如果在BST中找到 v,我们不会报告找到现有的整数v,而是执行三个可能的删除案例中的一个,这些案例将在三个单独的幻灯片中详细说明(我们建议您一个一个的尝试每个幻灯片)。
X Esc
上一个 PgUp
下一个 PgDn

The first case is the easiest: Vertex v is currently one of the leaf vertex of the BST.


Deletion of a leaf vertex is very easy: We just remove that leaf vertex — try Remove(5) on the example BST above (second click onwards after the first removal will do nothing — please refresh this page or go to another slide and return to this slide instead).


This part is clearly O(1) — on top of the earlier O(h) search-like effort.

X Esc
上一个 PgUp
下一个 PgDn

The second case is also not that hard: Vertex v is an (internal/root) vertex of the BST and it has exactly one child. Removing v without doing anything else will disconnect the BST.


Deletion of a vertex with one child is not that hard: We connect that vertex's only child with that vertex's parent — try Remove(23) on the example BST above (second click onwards after the first removal will do nothing — please refresh this page or go to another slide and return to this slide instead).


This part is also clearly O(1) — on top of the earlier O(h) search-like effort.

X Esc
上一个 PgUp
下一个 PgDn

The third case is the most complex among the three: Vertex v is an (internal/root) vertex of the BST and it has exactly two children. Removing v without doing anything else will disconnect the BST.


Deletion of a vertex with two children is as follow: We replace that vertex with its successor, and then delete its duplicated successor in its right subtree — try Remove(6) on the example BST above (second click onwards after the first removal will do nothing — please refresh this page or go to another slide and return to this slide instead).


This part requires O(h) due to the need to find the successor vertex — on top of the earlier O(h) search-like effort.

X Esc
上一个 PgUp
下一个 PgDn

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

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

e-Lecture: The content of this slide is hidden and only available for legitimate CS lecturer worldwide. Drop an email to visualgo.info at gmail dot com if you want to activate this CS lecturer-only feature and you are really a CS lecturer (show your University staff profile).

X Esc
上一个 PgUp
下一个 PgDn

Remove(v) runs in O(h) where h is the height of the BST. Removal case 3 (deletion of a vertex with two children is the 'heaviest' but it is not more than O(h)).


As you should have fully understand by now, h can be as tall as O(N) in a normal BST as shown in the random 'skewed right' example above. If we call Remove(FindMax()), i.e. we remove the current max integer, we will go from root down to the last leaf in O(N) time before removing it — not efficient.

X Esc
上一个 PgUp
下一个 PgDn
为了在“探索模式”中使生活更轻松,您可以使用以下选项创建新的BST:

  1. BST(然后你可以逐个插入几个整数),
  2. 你可能已经看过几次的两个电子讲座例子
  3. 随机BST(不太可能非常高),
  4. 向左/向右倾斜BST(具有N个顶点的高BST和具有N-1个链接列表的边缘,以展示BST操作的最坏情况行为;在AVL树模式中禁用)。
X Esc
上一个 PgUp
下一个 PgDn

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


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

X Esc
上一个 PgUp
下一个 PgDn

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

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

先前是:

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上。

X Esc
上一个 PgUp
下一个 PgDn

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

height(41) = 3
height(20) = 2
height(20) = 3
height(65) = 3
height(41) = 4
height(65) = 2
X Esc
上一个 PgUp
下一个 PgDn

If we have N elements/items/keys in our BST, the lower bound height h > log2 N if we can somehow insert the N elements in perfect order so that the BST is perfectly balanced.


See the example shown above for N = 15 (a perfect BST which is rarely achievable in real life — try inserting any other integer and it will not be perfect anymore).

X Esc
上一个 PgUp
下一个 PgDn
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
X Esc
上一个 PgUp
下一个 PgDn

If we have N elements/items/keys in our BST, the upper bound height h < N if we insert the elements in ascending order (to get skewed right BST as shown above).


The height of such BST is h = N-1, so we have h < N.


Discussion: Do you know how to get skewed left BST instead?

X Esc
上一个 PgUp
下一个 PgDn

e-Lecture: The content of this slide is hidden and only available for legitimate CS lecturer worldwide. Drop an email to visualgo.info at gmail dot com if you want to activate this CS lecturer-only feature and you are really a CS lecturer (show your University staff profile).

X Esc
上一个 PgUp
下一个 PgDn

We have seen that most BST operations are in O(h) and combining the lower and upper bounds of h, we have log2 N < h < N.


There is a dramatic difference between log2 N and N and we have seen from the discussion of the lower bound that getting perfect BST (at all times) is near impossible...


So can we have BST that has height closer to log2 N, i.e. c * log2 N, for a small constant factor c? If we can, then BST operations that run in O(h) actually run in O(log N)...

X Esc
上一个 PgUp
下一个 PgDn

Introducing AVL Tree, invented by two Russian (Soviet) inventors: Georgy Adelson-Velskii and Evgenii Landis, back in 1962.


In AVL Tree, we will later see that its height h < 2 * log N (tighter analysis exist, but we will use easier analysis in VisuAlgo where c = 2). Therefore, most AVL Tree operations run in O(log N) time — efficient.


Insert(v) and Remove(v) update operations may change the height h of the AVL Tree, but we will see rotation operation(s) to maintain the AVL Tree height to be low.

X Esc
上一个 PgUp
下一个 PgDn

To have efficient performance, we shall not maintain height(v) attribute via the O(N) recursive method every time there is an update (Insert(v)/Remove(v)) operation.


Instead, we compute O(1): x.height = max(x.left.height, x.right.height) + 1 at the back of our Insert(v)/Remove(v) operation as only the height of vertices along the insertion/removal path may be affected. Thus, only O(h) vertices may change its height(v) attribute and in AVL Tree, h < 2 * log N.


Try Insert(37) on the example AVL Tree (ignore the resulting rotation for now, we will come back to it in the next few slides). Notice that only a few vertices along the insertion path: {41,20,29,32} increases their height by +1 and all other vertices will have their heights unchanged.

X Esc
上一个 PgUp
下一个 PgDn
让我们定义以下重要的AVL树不变量(永不改变的属性):如果| v.left.height - v.right.height |,则顶点v被称为高度平衡。 ≤1。
如果BST中的每个顶点都是高度平衡的,则根据上面的不变量将BST称为高度平衡。 这样的BST称为AVL Tree,就像上面的例子一样。
花点时间在这里暂停一会,并尝试插入一些新的随机顶点或删除一些随机存在的顶点。 生成的BST是否仍然被认为是高度平衡的?
X Esc
上一个 PgUp
下一个 PgDn

Adelson-Velskii and Landis claim that an AVL Tree (a height-balanced BST that satisfies AVL Tree invariant) with N vertices has height h < 2 * log2 N.


The proof relies on the concept of minimum-size AVL Tree of a certain height h.


Let Nh be the minimum number of vertices in a height-balanced AVL Tree of height h.


The first few values of Nh are N0 = 1 (a single root vertex), N1 = 2 (a root vertex with either one left child or one right child only), N2 = 4, N3 = 7, N4 = 12, N5 = 20 (see the background picture), and so on (see the next two slides).

X Esc
上一个 PgUp
下一个 PgDn

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

Proof-2

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

X Esc
上一个 PgUp
下一个 PgDn
Nh = 1 + Nh-1 + Nh-2 (高度为h的最小尺寸AVL树的公式)
Nh > 1 + 2*Nh-2 (as 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 (as N0 = 1)
Proof-3
X Esc
上一个 PgUp
下一个 PgDn
N ≥ Nh > 2h/2 (结合前两张幻灯片)
N > 2h/2
log2(N) > log2(2h/2) (两张幻灯片都是log2 )
log2(N) > h/2 (等式化简)
2 * log2(N) > h or h < 2 * log2(N)
h = O(log(N)) (最后结论)
Proof-4
X Esc
上一个 PgUp
下一个 PgDn

Look at the example BST again. See that all vertices are height-balanced, an AVL Tree.


To quickly detect if a vertex v is height balanced or not, we modify the AVL Tree invariant (that has absolute function inside) into: bf(v) = v.left.height - v.right.height.


Now try Insert(37) on the example AVL Tree again. A few vertices along the insertion path: {41,20,29,32} increases their height by +1. Vertices {29,20} will no longer be height-balanced after this insertion (and will be rotated later — discussed in the next few slides), i.e. bf(29) = -2 and bf(20) = -2 too. We need to restore the balance.

X Esc
上一个 PgUp
下一个 PgDn
Tree Rotation

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

X Esc
上一个 PgUp
下一个 PgDn
BSTVertex rotateLeft(BSTVertex T) // pre-req: T.right != null
BSTVertex w = T.right // rotateRight is the mirror copy of this
w.parent = T.parent // this method is hard to get right for newbie
T.parent = w
T.right = w.left
if (w.left != null) w.left.parent = T
w.left = T
// update the height of T and then w here
return w
X Esc
上一个 PgUp
下一个 PgDn
Four Cases

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

X Esc
上一个 PgUp
下一个 PgDn
  1. Just insert v as in normal BST,
  2. Walk up the AVL Tree from the insertion point back to the root and at every step, we update the height and balance factor of the affected vertices:
    1. Stop at the first vertex that is out-of-balance (+2 or -2), if any,
    2. Use one of the four tree rotation cases to rebalance it again, e.g. try Insert(37) on the example above and notice by calling rotateLeft(29) once, we fix the imbalance issue.

Discussion: Is there other tree rotation cases for Insert(v) operation of AVL Tree?

X Esc
上一个 PgUp
下一个 PgDn

e-Lecture: The content of this slide is hidden and only available for legitimate CS lecturer worldwide. Drop an email to visualgo.info at gmail dot com if you want to activate this CS lecturer-only feature and you are really a CS lecturer (show your University staff profile).

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

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

X Esc
上一个 PgUp
下一个 PgDn

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


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

X Esc
上一个 PgUp
下一个 PgDn

We will end this module with a few more interesting things about BST and balanced BST (especially AVL Tree).

X Esc
上一个 PgUp
下一个 PgDn

e-Lecture: The content of this slide is hidden and only available for legitimate CS lecturer worldwide. Drop an email to visualgo.info at gmail dot com if you want to activate this CS lecturer-only feature and you are really a CS lecturer (show your University staff profile).

X Esc
上一个 PgUp
下一个 PgDn

e-Lecture: The content of this slide is hidden and only available for legitimate CS lecturer worldwide. Drop an email to visualgo.info at gmail dot com if you want to activate this CS lecturer-only feature and you are really a CS lecturer (show your University staff profile).

X Esc
上一个 PgUp
下一个 PgDn

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

X Esc
上一个 PgUp
下一个 PgDn

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

X Esc
上一个 PgUp
下一个 PgDn

e-Lecture: The content of this slide is hidden and only available for legitimate CS lecturer worldwide. Drop an email to visualgo.info at gmail dot com if you want to activate this CS lecturer-only feature and you are really a CS lecturer (show your University staff profile).

X Esc
上一个 PgUp
下一个 PgDn
当操作进行时,状态面板将会有每个步骤的描述。
X Esc
上一个 PgUp
下一个 PgDn

e-Lecture: The content of this slide is hidden and only available for legitimate CS lecturer worldwide. Drop an email to visualgo.info at gmail dot com if you want to activate this CS lecturer-only feature and you are really a CS lecturer (show your University staff profile).

X Esc
上一个 PgUp
下一个 PgDn
使用用户控件控制动画!可用的快捷键有:
空格键:绘制/停止/重绘
左/右箭头:上一步/下一步
-/+:减缓/增加速度

X Esc
上一个 PgUp
下一个 PgDn

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.

X Esc
上一个 PgUp

创建

插入(v)

移除(v)

前驱/后继(v)

中序遍历

>

清空

Unbalanced Example

Balanced Example

随机

向左偏斜

向右偏斜

v =

执行

v =

执行

v =

找前驱

找后继

关于 团队 使用条款

关于

VisuAlgo在2011年由Steven Halim博士概念化,作为一个工具,帮助他的学生更好地理解数据结构和算法,让他们自己和自己的步伐学习基础。
VisuAlgo包含许多高级算法,这些算法在Steven Halim博士的书(“竞争规划”,与他的兄弟Felix Halim博士合作)和其他书中讨论。今天,一些高级算法的可视化/动画只能在VisuAlgo中找到。
虽然专门为新加坡国立大学(NUS)学生采取各种数据结构和算法类(例如CS1010,CS1020,CS2010,CS2020,CS3230和CS3230),作为在线学习的倡导者,我们希望世界各地的好奇心发现这些可视化也很有用。
VisuAlgo不是从一开始就设计为在小触摸屏(例如智能手机)上工作良好,因为需要满足许多复杂的算法可视化,需要大量的像素和点击并拖动手势进行交互。一个令人尊敬的用户体验的最低屏幕分辨率为1024x768,并且只有着陆页相对适合移动设备。
VisuAlgo是一个正在进行的项目,更复杂的可视化仍在开发中。
最令人兴奋的发展是自动问题生成器和验证器(在线测验系统),允许学生测试他们的基本数据结构和算法的知识。这些问题是通过一些规则随机生成的,学生的答案会在提交给我们的评分服务器后立即自动分级。这个在线测验系统,当它被更多的世界各地的CS教师采用,应该技术上消除许多大学的典型计算机科学考试手动基本数据结构和算法问题。通过在通过在线测验时设置小(但非零)的重量,CS教练可以(显着地)增加他/她的学生掌握这些基本问题,因为学生具有几乎无限数量的可以立即被验证的训练问题他们参加在线测验。培训模式目前包含12个可视化模块的问题。我们将很快添加剩余的8个可视化模块,以便VisuAlgo中的每个可视化模块都有在线测验组件。
另一个积极的发展分支是VisuAlgo的国际化子项目。我们要为VisuAlgo系统中出现的所有英语文本准备一个CS术语的数据库。这是一个很大的任务,需要众包。一旦系统准备就绪,我们将邀请VisuAlgo游客贡献,特别是如果你不是英语母语者。目前,我们还以各种语言写了有关VisuAlgo的公共注释:
zh, id, kr, vn, th.

团队

项目领导和顾问(2011年7月至今)
Dr Steven Halim, Senior Lecturer, School of Computing (SoC), National University of Singapore (NUS)
Dr Felix Halim, 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

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

致谢
这个项目是由来自NUS教学与学习发展中心(CDTL)的慷慨的教学增进赠款提供的。

使用条款

VisuAlgo是地球上的计算机科学社区免费。如果你喜欢VisuAlgo,我们对你的唯一的要求就是通过你知道的方式,比如:Facebook、Twitter、课程网页、博客评论、电子邮件等告诉其他计算机方面的学生/教师:VisuAlgo网站的神奇存在
如果您是数据结构和算法学生/教师,您可以直接将此网站用于您的课程。如果你从这个网站拍摄截图(视频),你可以使用屏幕截图(视频)在其他地方,只要你引用本网站的网址(http://visualgo.net)或出现在下面的出版物列表中作为参考。但是,您不能下载VisuAlgo(客户端)文件并将其托管在您自己的网站上,因为它是剽窃。到目前为止,我们不允许其他人分叉这个项目并创建VisuAlgo的变体。使用(客户端)的VisuAlgo的离线副本作为您的个人使用是很允许的。
请注意,VisuAlgo的在线测验组件本质上具有沉重的服务器端组件,并且没有简单的方法来在本地保存服务器端脚本和数据库。目前,公众只能使用“培训模式”来访问这些在线测验系统。目前,“测试模式”是一个更受控制的环境,用于使用这些随机生成的问题和自动验证在NUS的实际检查。其他感兴趣的CS教练应该联系史蒂文如果你想尝试这样的“测试模式”。
出版物名单
这项工作在2012年ACM ICPC世界总决赛(波兰,华沙)和IOI 2012年IOI大会(意大利Sirmione-Montichiari)的CLI讲习班上进行了简要介绍。您可以点击此链接阅读我们2012年关于这个系统的文章(它在2012年还没有被称为VisuAlgo)。
这项工作主要由我过去的学生完成。最近的最后报告是:Erin,Wang Zi,Rose,Ivan。
错误申报或请求添加新功能
VisuAlgo不是一个完成的项目。 Steven Halim博士仍在积极改进VisuAlgo。如果您在使用VisuAlgo并在我们的可视化页面/在线测验工具中发现错误,或者如果您想要求添加新功能,请联系Dr Steven Halim博士。他的联系邮箱是他的名字加谷歌邮箱后缀:StevenHalim@gmail.com。