@@ -245,13 +245,13 @@ public class BinarySearchOrderedST<Key extends Comparable<Key>, Value> implement
245
245
246
246
** 二叉树** 是一个空链接,或者是一个有左右两个链接的节点,每个链接都指向一颗子二叉树。
247
247
248
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /c11528f6-fc71-4a2b-8d2f-51b8954c38f1.jpg" width =" 180 " /> </div ><br >
248
+ <div align =" center " > <img src =" pics /c11528f6-fc71-4a2b-8d2f-51b8954c38f1.jpg" width =" 180 " /> </div ><br >
249
249
250
250
** 二叉查找树** (BST)是一颗二叉树,并且每个节点的值都大于等于其左子树中的所有节点的值而小于等于右子树的所有节点的值。
251
251
252
252
BST 有一个重要性质,就是它的中序遍历结果递增排序。
253
253
254
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /ef552ae3-ae0d-4217-88e6-99cbe8163f0c.jpg" width =" 200 " /> </div ><br >
254
+ <div align =" center " > <img src =" pics /ef552ae3-ae0d-4217-88e6-99cbe8163f0c.jpg" width =" 200 " /> </div ><br >
255
255
256
256
基本数据结构:
257
257
@@ -325,7 +325,7 @@ private Value get(Node x, Key key) {
325
325
326
326
当插入的键不存在于树中,需要创建一个新节点,并且更新上层节点的链接指向该节点,使得该节点正确地链接到树中。
327
327
328
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /58b70113-3876-49af-85a9-68eb00a72d59.jpg" width =" 200 " /> </div ><br >
328
+ <div align =" center " > <img src =" pics /58b70113-3876-49af-85a9-68eb00a72d59.jpg" width =" 200 " /> </div ><br >
329
329
330
330
``` java
331
331
@Override
@@ -354,11 +354,11 @@ private Node put(Node x, Key key, Value value) {
354
354
355
355
最好的情况下树是完全平衡的,每条空链接和根节点的距离都为 logN。
356
356
357
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /c395a428-827c-405b-abd7-8a069316f583.jpg" width =" 200 " /> </div ><br >
357
+ <div align =" center " > <img src =" pics /c395a428-827c-405b-abd7-8a069316f583.jpg" width =" 200 " /> </div ><br >
358
358
359
359
在最坏的情况下,树的高度为 N。
360
360
361
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /5ea609cb-8ad4-4c4c-aee6-45a40a81794a.jpg" width =" 200 " /> </div ><br >
361
+ <div align =" center " > <img src =" pics /5ea609cb-8ad4-4c4c-aee6-45a40a81794a.jpg" width =" 200 " /> </div ><br >
362
362
363
363
## 4. floor()
364
364
@@ -436,7 +436,7 @@ private Node min(Node x) {
436
436
437
437
令指向最小节点的链接指向最小节点的右子树。
438
438
439
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /31b7e8de-ed11-4f69-b5fd-ba454120ac31.jpg" width =" 450 " /> </div ><br >
439
+ <div align =" center " > <img src =" pics /31b7e8de-ed11-4f69-b5fd-ba454120ac31.jpg" width =" 450 " /> </div ><br >
440
440
441
441
``` java
442
442
public void deleteMin() {
@@ -457,7 +457,7 @@ public Node deleteMin(Node x) {
457
457
- 如果待删除的节点只有一个子树, 那么只需要让指向待删除节点的链接指向唯一的子树即可;
458
458
- 否则,让右子树的最小节点替换该节点。
459
459
460
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /23b9d625-ef28-42b5-bb22-d7aedd007e16.jpg" width =" 400 " /> </div ><br >
460
+ <div align =" center " > <img src =" pics /23b9d625-ef28-42b5-bb22-d7aedd007e16.jpg" width =" 400 " /> </div ><br >
461
461
462
462
``` java
463
463
public void delete(Key key) {
@@ -520,7 +520,7 @@ private List<Key> keys(Node x, Key l, Key h) {
520
520
521
521
2-3 查找树引入了 2- 节点和 3- 节点,目的是为了让树平衡。一颗完美平衡的 2-3 查找树的所有空链接到根节点的距离应该是相同的。
522
522
523
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /1097658b-c0e6-4821-be9b-25304726a11c.jpg" width =" 160px " /> </div ><br >
523
+ <div align =" center " > <img src =" pics /1097658b-c0e6-4821-be9b-25304726a11c.jpg" width =" 160px " /> </div ><br >
524
524
525
525
## 1. 插入操作
526
526
@@ -530,11 +530,11 @@ private List<Key> keys(Node x, Key l, Key h) {
530
530
531
531
- 如果插入到 2- 节点上,那么直接将新节点和原来的节点组成 3- 节点即可。
532
532
533
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /0c6f9930-8704-4a54-af23-19f9ca3e48b0.jpg" width =" 350 " /> </div ><br >
533
+ <div align =" center " > <img src =" pics /0c6f9930-8704-4a54-af23-19f9ca3e48b0.jpg" width =" 350 " /> </div ><br >
534
534
535
535
- 如果是插入到 3- 节点上,就会产生一个临时 4- 节点时,需要将 4- 节点分裂成 3 个 2- 节点,并将中间的 2- 节点移到上层节点中。如果上移操作继续产生临时 4- 节点则一直进行分裂上移,直到不存在临时 4- 节点。
536
536
537
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /7002c01b-1ed5-475a-9e5f-5fc8a4cdbcc0.jpg" width =" 460 " /> </div ><br >
537
+ <div align =" center " > <img src =" pics /7002c01b-1ed5-475a-9e5f-5fc8a4cdbcc0.jpg" width =" 460 " /> </div ><br >
538
538
539
539
## 2. 性质
540
540
@@ -546,7 +546,7 @@ private List<Key> keys(Node x, Key l, Key h) {
546
546
547
547
红黑树是 2-3 查找树,但它不需要分别定义 2- 节点和 3- 节点,而是在普通的二叉查找树之上,为节点添加颜色。指向一个节点的链接颜色如果为红色,那么这个节点和上层节点表示的是一个 3- 节点,而黑色则是普通链接。
548
548
549
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /f1912ba6-6402-4321-9aa8-13d32fd121d1.jpg" width =" 240 " /> </div ><br >
549
+ <div align =" center " > <img src =" pics /f1912ba6-6402-4321-9aa8-13d32fd121d1.jpg" width =" 240 " /> </div ><br >
550
550
551
551
红黑树具有以下性质:
552
552
@@ -555,7 +555,7 @@ private List<Key> keys(Node x, Key l, Key h) {
555
555
556
556
画红黑树时可以将红链接画平。
557
557
558
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /f5cb6028-425d-4939-91eb-cca9dd6b6c6c.jpg" width =" 220 " /> </div ><br >
558
+ <div align =" center " > <img src =" pics /f5cb6028-425d-4939-91eb-cca9dd6b6c6c.jpg" width =" 220 " /> </div ><br >
559
559
560
560
``` java
561
561
public class RedBlackBST <Key extends Comparable<Key > , Value > extends BST<Key , Value > {
@@ -575,7 +575,7 @@ public class RedBlackBST<Key extends Comparable<Key>, Value> extends BST<Key, Va
575
575
576
576
因为合法的红链接都为左链接,如果出现右链接为红链接,那么就需要进行左旋转操作。
577
577
578
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /f4d534ab-0092-4a81-9e5b-ae889b9a72be.jpg" width =" 480 " /> </div ><br >
578
+ <div align =" center " > <img src =" pics /f4d534ab-0092-4a81-9e5b-ae889b9a72be.jpg" width =" 480 " /> </div ><br >
579
579
580
580
``` java
581
581
public Node rotateLeft(Node h) {
@@ -594,7 +594,7 @@ public Node rotateLeft(Node h) {
594
594
595
595
进行右旋转是为了转换两个连续的左红链接,这会在之后的插入过程中探讨。
596
596
597
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /63c8ffea-a9f2-4ebe-97d1-d71be71246f9.jpg" width =" 480 " /> </div ><br >
597
+ <div align =" center " > <img src =" pics /63c8ffea-a9f2-4ebe-97d1-d71be71246f9.jpg" width =" 480 " /> </div ><br >
598
598
599
599
``` java
600
600
public Node rotateRight(Node h) {
@@ -613,7 +613,7 @@ public Node rotateRight(Node h) {
613
613
614
614
一个 4- 节点在红黑树中表现为一个节点的左右子节点都是红色的。分裂 4- 节点除了需要将子节点的颜色由红变黑之外,同时需要将父节点的颜色由黑变红,从 2-3 树的角度看就是将中间节点移到上层节点。
615
615
616
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /094b279a-b2db-4be7-87a3-b2a039c7448e.jpg" width =" 270 " /> </div ><br >
616
+ <div align =" center " > <img src =" pics /094b279a-b2db-4be7-87a3-b2a039c7448e.jpg" width =" 270 " /> </div ><br >
617
617
618
618
``` java
619
619
void flipColors(Node h) {
@@ -631,7 +631,7 @@ void flipColors(Node h) {
631
631
- 如果左子节点是红色的,而且左子节点的左子节点也是红色的,进行右旋转;
632
632
- 如果左右子节点均为红色的,进行颜色转换。
633
633
634
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /4c457532-550b-4eca-b881-037b84b4934b.jpg" width =" 430 " /> </div ><br >
634
+ <div align =" center " > <img src =" pics /4c457532-550b-4eca-b881-037b84b4934b.jpg" width =" 430 " /> </div ><br >
635
635
636
636
``` java
637
637
@Override
@@ -756,7 +756,7 @@ public class Transaction {
756
756
757
757
对于 N 个键,M 条链表 (N>M),如果哈希函数能够满足均匀性的条件,每条链表的大小趋向于 N/M,因此未命中的查找和插入操作所需要的比较次数为 \~ N/M。
758
758
759
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /cbbfe06c-f0cb-47c4-bf7b-2780aebd98b2.png" width =" 330px " > </div ><br >
759
+ <div align =" center " > <img src =" pics /cbbfe06c-f0cb-47c4-bf7b-2780aebd98b2.png" width =" 330px " > </div ><br >
760
760
761
761
## 3. 线性探测法
762
762
@@ -765,7 +765,7 @@ public class Transaction {
765
765
使用线性探测法,数组的大小 M 应当大于键的个数 N(M>N)。
766
766
767
767
768
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /0dbc4f7d-05c9-4aae-8065-7b7ea7e9709e.gif" width =" 350px " > </div ><br >
768
+ <div align =" center " > <img src =" pics /0dbc4f7d-05c9-4aae-8065-7b7ea7e9709e.gif" width =" 350px " > </div ><br >
769
769
770
770
``` java
771
771
public class LinearProbingHashST <Key, Value> implements UnorderedST<Key , Value > {
@@ -867,7 +867,7 @@ public void delete(Key key) {
867
867
线性探测法的成本取决于连续条目的长度,连续条目也叫聚簇。当聚簇很长时,在查找和插入时也需要进行很多次探测。例如下图中 2\~ 4 位置就是一个聚簇。
868
868
869
869
870
- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com /ace20410-f053-4c4a-aca4-2c603ff11bbe.png" width =" 340px " > </div ><br >
870
+ <div align =" center " > <img src =" pics /ace20410-f053-4c4a-aca4-2c603ff11bbe.png" width =" 340px " > </div ><br >
871
871
872
872
α = N/M,把 α 称为使用率。理论证明,当 α 小于 1/2 时探测的预计次数只在 1.5 到 2.5 之间。为了保证散列表的性能,应当调整数组的大小,使得 α 在 [ 1/4, 1/2] 之间。
873
873
0 commit comments