auto commit
This commit is contained in:
parent
f7a8dbb1df
commit
6f74f1777b
18
notes/算法.md
18
notes/算法.md
|
@ -84,7 +84,7 @@
|
||||||
|
|
||||||
指数函数可以转换为线性函数,从而在函数图像上显示的更直观。
|
指数函数可以转换为线性函数,从而在函数图像上显示的更直观。
|
||||||
|
|
||||||
T(N)=aN<sup>3</sup> 转换为 lg(T(N))=3lgN+lga
|
<img src="https://latex.codecogs.com/gif.latex?T(N)=aN^3"/> 转换为 <img src="https://latex.codecogs.com/gif.latex?lg(T(N))=3lgN+lga"/>
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//5510045a-8f32-487f-a756-463e51a6dab0.png"/> </div><br>
|
<div align="center"> <img src="../pics//5510045a-8f32-487f-a756-463e51a6dab0.png"/> </div><br>
|
||||||
|
|
||||||
|
@ -149,14 +149,13 @@ public class ThreeSumFast {
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
for (int j = i + 1; j < N; j++) {
|
for (int j = i + 1; j < N; j++) {
|
||||||
for (int k = j + 1; k < N; k++) {
|
// rank() 方法返回元素在数组中的下标,如果元素不存在,这里会返回 -1。
|
||||||
// rank() 方法返回元素在数组中的下标,如果元素不存在,这里会返回 -1。应该注意这里的下标必须大于 j,这样就不会重复统计了。
|
// 应该注意这里的下标必须大于 j,这样就不会重复统计了。
|
||||||
if (BinarySearch.rank(-a[i] - a[j], a) > j) {
|
if (BinarySearch.rank(-a[i] - a[j], a) > j) {
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,8 +189,7 @@ public class ThreeSumFast {
|
||||||
|
|
||||||
**均摊分析**
|
**均摊分析**
|
||||||
|
|
||||||
将所有操作的总成本所以操作总数来将成本均摊。例如对一个空栈进行 N 次连续的 push() 调用需要访问数组的元素为 N+4+8+16+...+2N=5N-4(N 是向数组写入元素,其余的都是调整数组大小时进行复制需要的访问数组操作),均摊后每次操作访问数组的平均次数为常数。
|
将所有操作的总成本除于操作总数来将成本均摊。例如对一个空栈进行 N 次连续的 push() 调用需要访问数组的元素为 N+4+8+16+...+2N=5N-4(N 是向数组写入元素,其余的都是调整数组大小时进行复制需要的访问数组操作),均摊后每次操作访问数组的平均次数为常数。
|
||||||
|
|
||||||
|
|
||||||
# 排序
|
# 排序
|
||||||
|
|
||||||
|
@ -219,7 +217,7 @@ private void exch(Comparable[] a, int i, int j){
|
||||||
|
|
||||||
### 1.2 选择排序
|
### 1.2 选择排序
|
||||||
|
|
||||||
找到数组中的最小元素,然后将它与数组的第一个元素交换位置。然后再从剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。不断进行这样的操作,直到将整个数组排序。
|
找到数组中的最小元素,将它与数组的第一个元素交换位置。再从剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。不断进行这样的操作,直到将整个数组排序。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//222768a7-914f-4d64-b874-d98f3b926fb6.jpg"/> </div><br>
|
<div align="center"> <img src="../pics//222768a7-914f-4d64-b874-d98f3b926fb6.jpg"/> </div><br>
|
||||||
|
|
||||||
|
@ -242,7 +240,7 @@ public class Selection {
|
||||||
|
|
||||||
### 1.3 插入排序
|
### 1.3 插入排序
|
||||||
|
|
||||||
将一个元素插入到已排序的数组中,使得插入之后的数组也是有序的。插入排序从左到右插入每个元素,每次插入之后左部的子数组是有序的。
|
入排序从左到右进行,每次都将当前元素插入到左部已经排序的数组中,使得插入之后左部数组依然有序。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//065c3bbb-3ea0-4dbf-8f26-01d0e0ba7db7.png"/> </div><br>
|
<div align="center"> <img src="../pics//065c3bbb-3ea0-4dbf-8f26-01d0e0ba7db7.png"/> </div><br>
|
||||||
|
|
||||||
|
@ -307,6 +305,8 @@ public class Shell {
|
||||||
|
|
||||||
### 2.1 归并方法
|
### 2.1 归并方法
|
||||||
|
|
||||||
|
归并方法将数组中两个已经排序的部分归并成一个。
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public class MergeSort {
|
public class MergeSort {
|
||||||
private static Comparable[] aux;
|
private static Comparable[] aux;
|
||||||
|
@ -349,7 +349,7 @@ private static void sort(Comparable[] a, int lo, int hi) {
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//c7665f73-c52f-4ce4-aed3-592bbd76265b.png"/> </div><br>
|
<div align="center"> <img src="../pics//c7665f73-c52f-4ce4-aed3-592bbd76265b.png"/> </div><br>
|
||||||
|
|
||||||
很容易看出该排序算法的时间复杂度为 O(Nlg<sub>N</sub>)。
|
因为每次都将问题对半分成两个子问题,而这种对半分的算法复杂度一般为 O(Nlg<sub>N</sub>),因此该归并排序方法的时间复杂度也为 O(Nlg<sub>N</sub>)。
|
||||||
|
|
||||||
因为小数组的递归操作会过于频繁,因此使用插入排序来处理小数组将会获得更高的性能。
|
因为小数组的递归操作会过于频繁,因此使用插入排序来处理小数组将会获得更高的性能。
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user