auto commit
This commit is contained in:
37
notes/算法.md
37
notes/算法.md
@ -48,23 +48,23 @@
|
||||
|
||||
## 数学模型
|
||||
|
||||
<font size=4> **1. 近似** </font></br>
|
||||
### 1. 近似
|
||||
|
||||
使用 \~f(N) 来表示所有随着 N 的增大除以 f(N) 的结果趋近于 1 的函数 , 例如 N<sup>3</sup>/6-N<sup>2</sup>/2+N/3 \~ N<sup>3</sup>/6。
|
||||
|
||||
<div align="center"> <img src="../pics//8f1e2db5-a59b-4633-8b61-6b8b9505b8ea.png" width="600"/> </div><br>
|
||||
|
||||
<font size=4> **2. 增长数量级** </font></br>
|
||||
### 2. 增长数量级
|
||||
|
||||
增长数量级将算法与它的实现隔离开来,一个算法的增长数量级为 N<sup>3</sup> 与它是否用 Java 实现,是否运行于特定计算机上无关。
|
||||
|
||||
<div align="center"> <img src="../pics//521969c9-71f6-44a5-9c78-118530e5c135.png" width="700"/> </div><br>
|
||||
|
||||
<font size=4> **3. 内循环** </font></br>
|
||||
### 3. 内循环
|
||||
|
||||
执行最频繁的指令决定了程序执行的总时间,把这些指令称为程序的内循环。
|
||||
|
||||
<font size=4> **4. 成本模型** </font></br>
|
||||
### 4. 成本模型
|
||||
|
||||
使用成本模型来评估算法,例如数组的访问次数就是一种成本模型。
|
||||
|
||||
@ -93,7 +93,7 @@ public class ThreeSum {
|
||||
|
||||
该算法的内循环为`if (a[i] + a[j] + a[k] == 0)`语句,总共执行的次数为 N(N-1)(N-2) = N<sup>3</sup>/6 - N<sup>2</sup>/2 + N/3,因此它的近似执行次数为 \~N<sup>3</sup>/6,增长数量级为 N<sup>3</sup>。
|
||||
|
||||
**改进**
|
||||
<font size=4> **改进** </font></br>
|
||||
|
||||
通过将数组先排序,对两个元素求和,并用二分查找方法查找是否存在该和的相反数,如果存在,就说明存在三元组的和为 0。
|
||||
|
||||
@ -131,31 +131,23 @@ public class ThreeSumFast {
|
||||
|
||||
## 注意事项
|
||||
|
||||
<font size=4> **1. 大常数** </font></br>
|
||||
|
||||
### 1. 大常数
|
||||
|
||||
在求近似时,如果低级项的常数系数很大,那么近似的结果就是错误的。
|
||||
|
||||
<font size=4> **2. 缓存** </font></br>
|
||||
|
||||
|
||||
### 2. 缓存
|
||||
|
||||
计算机系统会使用缓存技术来组织内存,访问数组相邻的元素会比访问不相邻的元素快很多。
|
||||
|
||||
<font size=4> **3. 对最坏情况下的性能的保证** </font></br>
|
||||
|
||||
|
||||
### 3. 对最坏情况下的性能的保证
|
||||
|
||||
在核反应堆、心脏起搏器或者刹车控制器中的软件,最坏情况下的性能是十分重要的。
|
||||
|
||||
<font size=4> **4. 随机化算法** </font></br>
|
||||
|
||||
|
||||
### 4. 随机化算法
|
||||
|
||||
通过打乱输入,去除算法对输入的依赖。
|
||||
|
||||
<font size=4> **5. 均摊分析** </font></br>
|
||||
|
||||
### 5. 均摊分析
|
||||
|
||||
将所有操作的总成本除于操作总数来将成本均摊。例如对一个空栈进行 N 次连续的 push() 调用需要访问数组的元素为 N+4+8+16+...+2N=5N-4(N 是向数组写入元素,其余的都是调整数组大小时进行复制需要的访问数组操作),均摊后每次操作访问数组的平均次数为常数。
|
||||
|
||||
@ -169,7 +161,6 @@ first-in-last-out(FILO)
|
||||
|
||||
<font size=4> **1. 数组实现** </font></br>
|
||||
|
||||
|
||||
```java
|
||||
public class ResizeArrayStack<Item> implements Iterable<Item> {
|
||||
private Item[] a = (Item[]) new Object[1];
|
||||
@ -280,7 +271,6 @@ first-in-first-out(FIFO)
|
||||
|
||||
<div align="center"> <img src="../pics//c64f91e2-f5a8-436b-8663-b8f3fba3e098.png" width="300"/> </div><br>
|
||||
|
||||
|
||||
下面是队列的链表实现,需要维护 first 和 last 节点指针,分别指向队首和队尾。
|
||||
|
||||
这里需要考虑让哪个指针指针链表头部节点,哪个指针指向链表尾部节点。因为出队列操作需要让队首元素的下一个元素成为队首,就需要容易获取下一个元素,而链表的头部节点的 next 指针指向下一个元素,因此让队首指针 first 指针链表的开头。
|
||||
@ -482,7 +472,6 @@ private void exch(Comparable[] a, int i, int j){
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 选择排序
|
||||
|
||||
找到数组中的最小元素,将它与数组的第一个元素交换位置。再从剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。不断进行这样的操作,直到将整个数组排序。
|
||||
@ -529,7 +518,7 @@ public class Insertion {
|
||||
|
||||
插入排序对于部分有序数组和小规模数组特别高效。
|
||||
|
||||
**选择排序和插入排序的比较**
|
||||
<font size=3> **选择排序和插入排序的比较** </font> </br>
|
||||
|
||||
对于随机排序的无重复主键的数组,插入排序和选择排序的运行时间是平方级别的,两者之比是一个较小的常数。
|
||||
|
||||
@ -897,10 +886,8 @@ public static Comparable select(Comparable[] a, int k) {
|
||||
|
||||
<div align="center"> <img src="../pics//b69d7184-ab62-4957-ba29-fb4fa25f9b65.jpg"/> </div><br>
|
||||
|
||||
|
||||
<font size=4> **2. 有序符号表** </font></br>
|
||||
|
||||
|
||||
<div align="center"> <img src="../pics//ba6ae411-82da-4d86-a434-6776d1731e8e.jpg"/> </div><br>
|
||||
|
||||
有序符号表的键需要实现 Comparable 接口。
|
||||
@ -909,8 +896,6 @@ public static Comparable select(Comparable[] a, int k) {
|
||||
|
||||
<font size=4> **3. 二分查找实现有序符号表** </font></br>
|
||||
|
||||
|
||||
|
||||
使用一对平行数组,一个存储键一个存储值。
|
||||
|
||||
需要创建一个 Key 类型的 Comparable 对象数组和一个 Value 类型的 Object 对象数组。
|
||||
|
Reference in New Issue
Block a user