diff --git a/notes/算法.md b/notes/算法.md index 9ffa5bc3..fea7d455 100644 --- a/notes/算法.md +++ b/notes/算法.md @@ -823,9 +823,9 @@ public Key delMax() { 交换之后需要进行下沉操作维持堆的有序状态。 -

+

-

+

```java public static void sort(Comparable[] a){ @@ -1144,7 +1144,7 @@ public Node deleteMin(Node x) { - 如果待删除的节点只有一个子树,那么只需要让指向待删除节点的链接指向唯一的子树即可; - 否则,让右子树的最小节点替换该节点。 -

+

```java public void delete(Key key) { @@ -1194,7 +1194,7 @@ private void keys(Node x, Queue queue, Key lo, Key hi) { ## 2-3 查找树 -

+

2-3 查找树引入了 2- 节点和 3- 节点,目的是为了让树更平衡。一颗完美平衡的 2-3 查找树的所有空链接到根节点的距离应该是相同的。 @@ -1206,11 +1206,11 @@ private void keys(Node x, Queue queue, Key lo, Key hi) { 插入到 2- 节点上,那么直接将新节点和原来的节点组成 3- 节点即可。 -

+

如果是插入到 3- 节点上,就会产生一个临时 4- 节点时,需要将 4- 节点分裂成 3 个 2- 节点,并将中间的 2- 节点移到上层节点中。如果上移操作继续产生临时 4- 节点则一直进行分裂上移,直到不存在临时 4- 节点。 -

+

### 2. 性质 @@ -1224,7 +1224,7 @@ private void keys(Node x, Queue queue, Key lo, Key hi) { 2-3 查找树需要用到 2- 节点和 3- 节点,红黑树使用红链接来实现 3- 节点。指向一个节点的链接颜色如果为红色,那么这个节点和上层节点表示的是一个 3- 节点,而黑色则是普通链接。 -

+

红黑树具有以下性质: @@ -1267,9 +1267,7 @@ public class RedBlackBST, Value> { 因为合法的红链接都为左链接,如果出现右链接为红链接,那么就需要进行左旋转操作。 -

- -

+

```java public Node rotateLeft(Node h) { @@ -1288,9 +1286,7 @@ public Node rotateLeft(Node h) { 进行右旋转是为了转换两个连续的左红链接,这会在之后的插入过程中探讨。 -

- -

+

```java public Node rotateRight(Node h) { @@ -1308,9 +1304,7 @@ public Node rotateRight(Node h) { 一个 4- 节点在红黑树中表现为一个节点的左右子节点都是红色的。分裂 4- 节点除了需要将子节点的颜色由红变黑之外,同时需要将父节点的颜色由黑变红,从 2-3 树的角度看就是将中间节点移到上层节点。 -

- -

+

```java void flipColors(Node h){ @@ -1328,7 +1322,7 @@ void flipColors(Node h){ - 如果左子节点是红色的,而且左子节点的左子节点也是红色的,进行右旋转; - 如果左右子节点均为红色的,进行颜色转换。 -

+

```java public void put(Key key, Value val) { @@ -1356,23 +1350,7 @@ private Node put(Node x, Key key, Value val) { 根节点一定为黑色,因为根节点没有上层节点,也就没有上层节点的左链接指向根节点。flipColors() 有可能会使得根节点的颜色变为红色,每当根节点由红色变成黑色时树的黑链接高度加 1. -### 5. 删除最小键 - -如果最小键在一个 2- 节点中,那么删除该键会留下一个空链接,就破坏了平衡性,因此要确保最小键不在 2- 节点中。 - -将 2- 节点转换成 3- 节点或者 4- 节点有两种方法,一种是向上层节点拿一个 key,一种是向兄弟节点拿一个 key。如果上层节点是 2- 节点,那么就没办法从上层节点拿 key 了,因此要保证删除路径上的所有节点都不是 2- 节点。在向下删除的过程中,保证以下情况之一发生: - -1. 如果当前节点的左子节点不是 2- 节点,完成; -2. 如果当前节点的左子节点是 2- 节点而它的兄弟节点不是 2- 节点,向兄弟节点拿一个 key 过来; -3. 如果当前节点的左子节点和它的兄弟节点都是 2- 节点,将左子节点、父节点中的最小键和最近的兄弟节点合并为一个 4- 节点。 - -

- -最后得到一个含有最小键的 3- 节点或者 4- 节点,直接从中删除。然后再从头分解所有临时的 4- 节点。 - -

- -### 6. 分析 +### 5. 分析 一颗大小为 N 的红黑树的高度不会超过 2logN。最坏的情况下是它所对应的 2-3 树,构成最左边的路径节点全部都是 3- 节点而其余都是 2- 节点。 @@ -1446,7 +1424,7 @@ public class Transaction{ 拉链法使用链表来存储 hash 值相同的键,从而解决冲突。此时查找需要分两步,首先查找 Key 所在的链表,然后在链表中顺序查找。 -

+

对于 N 个键,M 条链表 (N>M),如果哈希函数能够满足均匀性的条件,每条链表的大小趋向于 N/M,因此未命中的查找和插入操作所需要的比较次数为 \~N/M。 @@ -1454,7 +1432,7 @@ public class Transaction{ 线性探测法使用空位来解决冲突,当冲突发生时,向前探测一个空位来存储冲突的键。使用线程探测法,数组的大小 M 应当大于键的个数 N(M>N)。 -

+

```java public class LinearProbingHashST { @@ -1579,7 +1557,13 @@ private void resize(int cap) { ### 1. 各种符号表实现的比较 -

+| 算法 | 插入 | 查找 | 是否有序 | +| :---: | :---: | :---: | :---: | +| 二分查找实现的有序表 | logN | N | yes | +| 二叉查找树 | logN | logN | yes | +| 2-3 查找树 | logN | logN | yes | +| 拉链法实现的散列表 | logN | N/M | no | +| 线性探测法试下的删列表 | logN | 1 | no | 应当优先考虑散列表,当需要有序性操作时使用红黑树。 diff --git a/pics/08427d38-8df1-49a1-8990-e0ce5ee36ca2.png b/pics/08427d38-8df1-49a1-8990-e0ce5ee36ca2.png new file mode 100644 index 00000000..13d49836 Binary files /dev/null and b/pics/08427d38-8df1-49a1-8990-e0ce5ee36ca2.png differ diff --git a/pics/1f039a45-6b91-4f31-a2c2-6c63eb8bdb56.png b/pics/1f039a45-6b91-4f31-a2c2-6c63eb8bdb56.png new file mode 100644 index 00000000..eb4daeab Binary files /dev/null and b/pics/1f039a45-6b91-4f31-a2c2-6c63eb8bdb56.png differ diff --git a/pics/3290673d-edab-4678-8b2e-f18e0f6b7fc1.png b/pics/3290673d-edab-4678-8b2e-f18e0f6b7fc1.png new file mode 100644 index 00000000..8322e80a Binary files /dev/null and b/pics/3290673d-edab-4678-8b2e-f18e0f6b7fc1.png differ diff --git a/pics/4f48e806-f90b-4c09-a55f-ac0cd641c047.png b/pics/4f48e806-f90b-4c09-a55f-ac0cd641c047.png new file mode 100644 index 00000000..649d16cd Binary files /dev/null and b/pics/4f48e806-f90b-4c09-a55f-ac0cd641c047.png differ diff --git a/pics/51fb761d-8ce0-4472-92ff-2f227ac7888a.png b/pics/51fb761d-8ce0-4472-92ff-2f227ac7888a.png new file mode 100644 index 00000000..d49b1727 Binary files /dev/null and b/pics/51fb761d-8ce0-4472-92ff-2f227ac7888a.png differ diff --git a/pics/7f38a583-2f2e-4738-97af-510e6fb403a7.png b/pics/7f38a583-2f2e-4738-97af-510e6fb403a7.png new file mode 100644 index 00000000..57e71b9c Binary files /dev/null and b/pics/7f38a583-2f2e-4738-97af-510e6fb403a7.png differ diff --git a/pics/9110c1a0-8a54-4145-a814-2477d0128114.png b/pics/9110c1a0-8a54-4145-a814-2477d0128114.png new file mode 100644 index 00000000..68aa9f98 Binary files /dev/null and b/pics/9110c1a0-8a54-4145-a814-2477d0128114.png differ diff --git a/pics/af4639f9-af54-4400-aaf5-4e261d96ace7.png b/pics/af4639f9-af54-4400-aaf5-4e261d96ace7.png new file mode 100644 index 00000000..8de4fa4d Binary files /dev/null and b/pics/af4639f9-af54-4400-aaf5-4e261d96ace7.png differ diff --git a/pics/b4252c85-6fb0-4995-9a68-a1a5925fbdb1.png b/pics/b4252c85-6fb0-4995-9a68-a1a5925fbdb1.png new file mode 100644 index 00000000..59ea02cc Binary files /dev/null and b/pics/b4252c85-6fb0-4995-9a68-a1a5925fbdb1.png differ diff --git a/pics/dbb8516d-37ba-4e2c-b26b-eefd7de21b45.png b/pics/dbb8516d-37ba-4e2c-b26b-eefd7de21b45.png new file mode 100644 index 00000000..1ee66db8 Binary files /dev/null and b/pics/dbb8516d-37ba-4e2c-b26b-eefd7de21b45.png differ diff --git a/pics/e2f0d889-2330-424c-8193-198edebecff7.png b/pics/e2f0d889-2330-424c-8193-198edebecff7.png new file mode 100644 index 00000000..d747d6f3 Binary files /dev/null and b/pics/e2f0d889-2330-424c-8193-198edebecff7.png differ diff --git a/pics/ef280699-da36-4b38-9735-9b048a3c7fe0.png b/pics/ef280699-da36-4b38-9735-9b048a3c7fe0.png new file mode 100644 index 00000000..a54c85e1 Binary files /dev/null and b/pics/ef280699-da36-4b38-9735-9b048a3c7fe0.png differ diff --git a/pics/ff396233-1bb1-4e74-8bc2-d7c90146f5dd.png b/pics/ff396233-1bb1-4e74-8bc2-d7c90146f5dd.png new file mode 100644 index 00000000..4eaa11ba Binary files /dev/null and b/pics/ff396233-1bb1-4e74-8bc2-d7c90146f5dd.png differ