@@ -244,9 +244,11 @@ <h1 id="bst">二叉查找树(BST)</h1>
244
244
前面有章节说到了查找操作,包括线性查找和二分查找,线性查找效率比较低,二分又要求必须是有序的序列,
245
245
为了维持有序插入的代价比较高。能不能有一种插入和查找都比较快的数据结构呢?二叉查找树就是这样一种结构,可以高效地插入和查询节点。</ p >
246
246
< h1 id ="bst_1 "> BST 定义</ h1 >
247
- < p > 二叉查找树是这样一种二叉树结构,它的每个节点包含一个 key 和它附带的数据,对于每个内部节点 V:
248
- - 所有 key 小于 V 的都被存储在 V 的左子树
249
- - 所有 key 大于 V 的都存储在 V 的右子树</ p >
247
+ < p > 二叉查找树是这样一种二叉树结构,它的每个节点包含一个 key 和它附带的数据,对于每个内部节点 V:</ p >
248
+ < ul >
249
+ < li > 所有 key 小于 V 的都被存储在 V 的左子树</ li >
250
+ < li > 所有 key 大于 V 的都存储在 V 的右子树</ li >
251
+ </ ul >
250
252
< p > < img alt ="" src ="../bst.png " /> </ p >
251
253
< p > 注意这个限制条件,可别和堆搞混了。说白了就是对于每个内部节点,左子树的 key 都比它小,右子树都比它大。
252
254
如果中序遍历(二叉树遍历讲过了)这颗二叉树,你会发现输出的顺序正好是有序的。
@@ -380,15 +382,15 @@ <h4 id="_4">删除叶节点</h4>
380
382
< p > 这是最简单的一种情况,只需要把它的父亲指向它的指针设置为 None 就好。</ p >
381
383
< p > < img alt ="" src ="../bst_remove_leaf.png " /> </ p >
382
384
< h4 id ="_5 "> 删除只有一个孩子的节点</ h4 >
383
- < p > 删除有一个孩子的节点时,我们拿掉需要删除的节点,之后把它的父亲指向它的孩子就行,以为根据 BST
385
+ < p > 删除有一个孩子的节点时,我们拿掉需要删除的节点,之后把它的父亲指向它的孩子就行,因为根据 BST
384
386
左子树都小于节点,右子树都大于节点的特性,删除它之后这个条件依旧满足。</ p >
385
387
< p > < img alt ="" src ="../bst_remove_node_with_one_child.png " /> </ p >
386
388
< h4 id ="_6 "> 删除有两个孩子的内部节点</ h4 >
387
389
< p > 假如我们想删除 12 这个节点改怎么做呢?你的第一反应可能是按照下图的方式:</ p >
388
390
< p > < img alt ="" src ="../remove_interior_replace.png " /> </ p >
389
391
< p > 但是这种方式可能会影响树的高度,降低查找的效率。这里我们用另一种非常巧妙的方式。
390
392
还记得上边提到的吗,如果你中序遍历 BST 并且输出每个节点的 key,你会发现就是一个有序的数组。
391
- [1 4 12 23 29 37 41 60 71 84 90 100]。 这里我们定义两个概念,逻辑前任(predecessor)和后继(successor),请看下图:</ p >
393
+ < code > [1 4 12 23 29 37 41 60 71 84 90 100]</ code > 。 这里我们定义两个概念,逻辑前任(predecessor)和后继(successor),请看下图:</ p >
392
394
< p > < img alt ="" src ="../predecessor_successor.png " /> </ p >
393
395
< p > 12 在中序遍历中的逻辑前任和后继分别是 4 和 23 节点。于是我们还有一种方法来删除 12 这个节点:</ p >
394
396
< ul >
@@ -427,6 +429,7 @@ <h4 id="_6">删除有两个孩子的内部节点</h4>
427
429
def remove(self, key):
428
430
assert key in self
429
431
self.size -= 1
432
+ return self._bst_remove(self.root, key)
430
433
</ code > </ pre >
431
434
432
435
< p > 完整代码你可以在本章的 bst.py 找到。</ p >
0 commit comments