From c9718335fa9fa5ec03514a90e4a4f53233b92d5b Mon Sep 17 00:00:00 2001
From: CyC2018 <1029579233@qq.com>
Date: Thu, 12 Jul 2018 00:01:21 +0800
Subject: [PATCH] auto commit
---
README.md | 6 +++---
notes/算法.md | 52 +++++++++++++++++++++++++++------------------------
2 files changed, 31 insertions(+), 27 deletions(-)
diff --git a/README.md b/README.md
index ed5960b5..89625ec3 100644
--- a/README.md
+++ b/README.md
@@ -147,7 +147,7 @@ Google 开源项目的代码风格规范。
**授权相关**
-虽然没有加开源协议,但是默认允许非商业使用。
+虽然没有加开源协议,但是允许非商业性使用。
转载使用请注明出处,谢谢!
@@ -157,7 +157,7 @@ Google 开源项目的代码风格规范。
进行 Markdown 文档转换是因为 Github 使用的 GFM 不支持 MathJax 公式和 TOC 标记,所以需要替换 MathJax 公式为 CodeCogs 的云服务和重新生成 TOC 目录。
-这里提供了笔者实现的 GFM 文档转换工具的下载:[GFM-Converter](https://github.com/CyC2018/GFM-Converter)。
+这里提供了笔者实现的 GFM 文档转换工具的链接:[GFM-Converter](https://github.com/CyC2018/GFM-Converter)。
**排版指南**
@@ -165,7 +165,7 @@ Google 开源项目的代码风格规范。
笔记不使用 `![]()` 这种方式来引用图片,而是用 `` 标签。一方面是为了能够控制图片以合适的大小显示,另一方面是因为 GFM 不支持 `
![]() ` 让图片居中显示,只能使用 ` ` 达到居中的效果。
-这里提供了笔者实现的中英混排文档在线排版工具:[Text-Typesetting](https://github.com/CyC2018/Markdown-Typesetting)。
+这里提供了笔者实现的中英混排文档在线排版工具的链接:[Text-Typesetting](https://github.com/CyC2018/Markdown-Typesetting)。
**声明**
diff --git a/notes/算法.md b/notes/算法.md
index 31911cc9..df5a8049 100644
--- a/notes/算法.md
+++ b/notes/算法.md
@@ -24,8 +24,7 @@
* [堆排序](#堆排序)
* [小结](#小结)
* [六、查找](#六查找)
- * [链表实现无序符号表](#链表实现无序符号表)
- * [二分查找实现有序符号表](#二分查找实现有序符号表)
+ * [初级实现](#初级实现)
* [二叉查找树](#二叉查找树)
* [2-3 查找树](#2-3-查找树)
* [红黑树](#红黑树)
@@ -1178,7 +1177,9 @@ public interface OrderedST, Value> {
}
```
-## 链表实现无序符号表
+## 初级实现
+
+### 1. 链表实现无序符号表
```java
public class ListUnorderedST implements UnorderedST {
@@ -1253,7 +1254,7 @@ public class ListUnorderedST implements UnorderedST {
}
```
-## 二分查找实现有序符号表
+### 2. 二分查找实现有序符号表
使用一对平行数组,一个存储键一个存储值。
@@ -1308,7 +1309,7 @@ public class BinarySearchOrderedST, Value> implement
@Override
public void put(Key key, Value value) {
int index = rank(key);
- // 如果找到已经存在的节点键位 key,就更新这个节点的值为 value
+ // 如果找到已经存在的节点键为 key,就更新这个节点的值为 value
if (index < N && keys[index].compareTo(key) == 0) {
values[index] = value;
return;
@@ -1391,14 +1392,14 @@ public class BST, Value> implements OrderedST
@@ -1454,7 +1455,9 @@ private Node put(Node x, Key key, Value value) {
### 3. 分析
-二叉查找树的算法运行时间取决于树的形状,而树的形状又取决于键被插入的先后顺序。最好的情况下树是完全平衡的,每条空链接和根节点的距离都为 logN。
+二叉查找树的算法运行时间取决于树的形状,而树的形状又取决于键被插入的先后顺序。
+
+最好的情况下树是完全平衡的,每条空链接和根节点的距离都为 logN。
@@ -1467,8 +1470,7 @@ private Node put(Node x, Key key, Value value) {
floor(key):小于等于键的最大键
- 如果键小于根节点的键,那么 floor(key) 一定在左子树中;
-- 如果键大于根节点的键,需要先判断右子树中是否存在 floor(key),如果存在就找到,否则根节点就是 floor(key)。
-
+- 如果键大于根节点的键,需要先判断右子树中是否存在 floor(key),如果存在就返回,否则根节点就是 floor(key)。
```java
public Key floor(Key key) {
@@ -1497,7 +1499,7 @@ rank(key) 返回 key 的排名。
- 如果键和根节点的键相等,返回左子树的节点数;
- 如果小于,递归计算在左子树中的排名;
-- 如果大于,递归计算在右子树中的排名,并加上左子树的节点数,再加上 1(根节点)。
+- 如果大于,递归计算在右子树中的排名,加上左子树的节点数,再加上 1(根节点)。
```java
@Override
@@ -1793,15 +1795,15 @@ private Node put(Node x, Key key, Value value) {
- 一致性:相等的键应当有相等的 hash 值,两个键相等表示调用 equals() 返回的值相等。
- 高效性:计算应当简便,有必要的话可以把 hash 值缓存起来,在调用 hash 函数时直接返回。
-- 均匀性:所有键的 hash 值应当均匀地分布到 [0, M-1] 之间,这个条件至关重要,直接影响到散列表的性能。
+- 均匀性:所有键的 hash 值应当均匀地分布到 [0, M-1] 之间,如果不能满足这个条件,有可能产生很多冲突,从而导致散列表的性能下降。
除留余数法可以将整数散列到 [0, M-1] 之间,例如一个正整数 k,计算 k%M 既可得到一个 [0, M-1] 之间的 hash 值。注意 M 必须是一个素数,否则无法利用键包含的所有信息。例如 M 为 10k,那么只能利用键的后 k 位。
-对于其它数,可以将其转换成整数的形式,然后利用除留余数法。例如对于浮点数,可以将其表示成二进制形式,然后使用二进制形式的整数值进行除留余数法。
+对于其它数,可以将其转换成整数的形式,然后利用除留余数法。例如对于浮点数,可以将其的二进制形式转换成整数。
-对于有多部分组合的键,每部分都需要计算 hash 值,并且最后合并时需要让每部分 hash 值都具有同等重要的地位。可以将该键看成 R 进制的整数,键中每部分都具有不同的权值。
+对于多部分组合的类型,每个部分都需要计算 hash 值,这些 hash 值都具有同等重要的地位。为了达到这个目的,可以将该类型看成 R 进制的整数,每个部分都具有不同的权值。
-例如,字符串的散列函数实现如下
+例如,字符串的散列函数实现如下:
```java
int hash = 0;
@@ -1823,7 +1825,7 @@ Java 中的 hashCode() 实现了 hash 函数,但是默认使用对象的内存
int hash = (x.hashCode() & 0x7fffffff) % M;
```
-使用 Java 自带的 HashMap 等自带的哈希表实现时,只需要去实现 Key 类型的 hashCode() 函数即可。Java 规定 hashCode() 能够将键均匀分布于所有的 32 位整数,Java 中的 String、Integer 等对象的 hashCode() 都能实现这一点。以下展示了自定义类型如何实现 hashCode()。
+使用 Java 自带的 HashMap 等自带的哈希表实现时,只需要去实现 Key 类型的 hashCode() 函数即可。Java 规定 hashCode() 能够将键均匀分布于所有的 32 位整数,Java 中的 String、Integer 等对象的 hashCode() 都能实现这一点。以下展示了自定义类型如何实现 hashCode():
```java
public class Transaction {
@@ -1850,15 +1852,19 @@ public class Transaction {
### 2. 基于拉链法的散列表
-拉链法使用链表来存储 hash 值相同的键,从而解决冲突。此时查找需要分两步,首先查找 Key 所在的链表,然后在链表中顺序查找。
+拉链法使用链表来存储 hash 值相同的键,从而解决冲突。
+
+查找需要分两步,首先查找 Key 所在的链表,然后在链表中顺序查找。
+
+对于 N 个键,M 条链表 (N>M),如果 hash 函数能够满足均匀性的条件,每条链表的大小趋向于 N/M,因此未命中的查找和插入操作所需要的比较次数为 \~N/M。
-对于 N 个键,M 条链表 (N>M),如果哈希函数能够满足均匀性的条件,每条链表的大小趋向于 N/M,因此未命中的查找和插入操作所需要的比较次数为 \~N/M。
-
### 3. 基于线性探测法的散列表
-线性探测法使用空位来解决冲突,当冲突发生时,向前探测一个空位来存储冲突的键。使用线性探测法,数组的大小 M 应当大于键的个数 N(M>N)。
+线性探测法使用空位来解决冲突,当冲突发生时,向前探测一个空位来存储冲突的键。
+
+使用线性探测法,数组的大小 M 应当大于键的个数 N(M>N)。
@@ -1962,9 +1968,7 @@ public void delete(Key key) {
-α = N/M,把 α 称为利用率。理论证明,当 α 小于 1/2 时探测的预计次数只在 1.5 到 2.5 之间。
-
-为了保证散列表的性能,应当调整数组的大小,使得 α 在 [1/4, 1/2] 之间。
+α = N/M,把 α 称为使用率。理论证明,当 α 小于 1/2 时探测的预计次数只在 1.5 到 2.5 之间。为了保证散列表的性能,应当调整数组的大小,使得 α 在 [1/4, 1/2] 之间。
```java
private void resize() {