1
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
2
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
3
+ ** Table of Contents** * generated with [ DocToc] ( https://github.com/thlorenz/doctoc ) *
4
+
5
+ - [ 栈] ( #%E6%A0%88 )
6
+ - [ 原理] ( #%E5%8E%9F%E7%90%86 )
7
+ - [ 实现] ( #%E5%AE%9E%E7%8E%B0 )
8
+ - [ 应用] ( #%E5%BA%94%E7%94%A8 )
9
+ - [ 队列] ( #%E9%98%9F%E5%88%97 )
10
+ - [ 原理] ( #%E5%8E%9F%E7%90%86-1 )
11
+ - [ 实现] ( #%E5%AE%9E%E7%8E%B0-1 )
12
+ - [ 单链队列] ( #%E5%8D%95%E9%93%BE%E9%98%9F%E5%88%97 )
13
+ - [ 循环队列] ( #%E5%BE%AA%E7%8E%AF%E9%98%9F%E5%88%97 )
14
+ - [ 链表] ( #%E9%93%BE%E8%A1%A8 )
15
+ - [ 原理] ( #%E5%8E%9F%E7%90%86-2 )
16
+ - [ 实现] ( #%E5%AE%9E%E7%8E%B0-2 )
17
+ - [ 树] ( #%E6%A0%91 )
18
+ - [ 二叉树] ( #%E4%BA%8C%E5%8F%89%E6%A0%91 )
19
+ - [ 二分搜索树] ( #%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2%E6%A0%91 )
20
+ - [ 实现] ( #%E5%AE%9E%E7%8E%B0-3 )
21
+
22
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
23
+
1
24
# 栈
2
25
3
26
## 原理
@@ -418,7 +441,7 @@ _floor(node, v) {
418
441
}
419
442
```
420
443
421
- ** 排名** ,这是用于获取给定值的排名或者排名第几的节点的值,这两个操作也是相反的,所以这个只介绍如果获取排名第几的节点的值 。对于这个操作而言,我们需要略微的改造点代码,让每个节点拥有一个 ` size ` 属性。该属性表示该节点下有多少子节点(包含自身)。
444
+ ** 排名** ,这是用于获取给定值的排名或者排名第几的节点的值,这两个操作也是相反的,所以这个只介绍如何获取排名第几的节点的值 。对于这个操作而言,我们需要略微的改造点代码,让每个节点拥有一个 ` size ` 属性。该属性表示该节点下有多少子节点(包含自身)。
422
445
423
446
``` js
424
447
class Node {
@@ -430,6 +453,10 @@ class Node {
430
453
this .size = 1
431
454
}
432
455
}
456
+ // 新增代码
457
+ _getSize (node ) {
458
+ return node ? node .size : 0
459
+ }
433
460
_addChild (node , v ) {
434
461
if (! node) {
435
462
return new Node (v)
@@ -463,3 +490,28 @@ _select(node, k) {
463
490
}
464
491
```
465
492
493
+ 接下来讲解的是二分搜索树中最难实现的部分:删除节点。因为对于删除节点来说,会存在以下几种情况
494
+
495
+ - 需要删除的节点没有子树
496
+ - 需要删除的节点只有一条子树
497
+ - 需要删除的节点有左右两条树
498
+
499
+ 对于前两种情况很好解决,但是第三种情况就有难度了,所以先来实现相对简单的操作:删除最小节点,对于删除最小节点来说,是不存在第三种情况的,删除最大节点操作是和删除最小节点相反的,所以这里也就不再赘述。
500
+
501
+ ``` js
502
+ delectMin () {
503
+ this .root = this ._delectMin (this .root )
504
+ console .log (this .root )
505
+ }
506
+ _delectMin (node ) {
507
+ // 一直递归左子树
508
+ // 如果左子树为空,就判断节点是否拥有右子树
509
+ // 有右子树的话就把需要删除的节点替换为右子树
510
+ if ((node != null ) & ! node .left ) return node .right
511
+ node .left = this ._delectMin (node .left )
512
+ // 最后需要重新维护下节点的 `size`
513
+ node .size = this ._getSize (node .left ) + this ._getSize (node .right ) + 1
514
+ return node
515
+ }
516
+ ```
517
+
0 commit comments