auto commit
This commit is contained in:
parent
7991d0297e
commit
63745167d9
52
notes/算法.md
52
notes/算法.md
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
<div align="center"><img src="https://latex.codecogs.com/gif.latex?log(T(N))=3logN+loga"/></div> <br>
|
<div align="center"><img src="https://latex.codecogs.com/gif.latex?log(T(N))=3logN+loga"/></div> <br>
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//a9098783-c24a-45b2-a226-725a59b6768e.png" width="800"/> </div><br>
|
<div align="center"> <img src="../pics//a9098783-c24a-45b2-a226-725a59b6768e.png" width="600"/> </div><br>
|
||||||
|
|
||||||
## 数学模型
|
## 数学模型
|
||||||
|
|
||||||
|
@ -52,13 +52,13 @@
|
||||||
|
|
||||||
使用 \~f(N) 来表示所有随着 N 的增大除以 f(N) 的结果趋近于 1 的函数,例如 N<sup>3</sup>/6-N<sup>2</sup>/2+N/3 \~ N<sup>3</sup>/6。
|
使用 \~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//81eb9879-40f2-421a-87de-2b953cfe8c32.png" width="1000"/> </div><br>
|
<div align="center"> <img src="../pics//81eb9879-40f2-421a-87de-2b953cfe8c32.png" width="600"/> </div><br>
|
||||||
|
|
||||||
### 2. 增长数量级
|
### 2. 增长数量级
|
||||||
|
|
||||||
增长数量级将算法与它的实现隔离开来,一个算法的增长数量级为 N<sup>3</sup> 与它是否用 Java 实现,是否运行于特定计算机上无关。
|
增长数量级将算法与它的实现隔离开来,一个算法的增长数量级为 N<sup>3</sup> 与它是否用 Java 实现,是否运行于特定计算机上无关。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//051760ba-e658-401f-9a1c-15adcb405191.png" width="1000"/> </div><br>
|
<div align="center"> <img src="../pics//051760ba-e658-401f-9a1c-15adcb405191.png" width="600"/> </div><br>
|
||||||
|
|
||||||
### 3. 内循环
|
### 3. 内循环
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ public class ThreeSumFast {
|
||||||
|
|
||||||
first-in-last-out(FILO)
|
first-in-last-out(FILO)
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//cc7bfdeb-452e-4fae-9bc8-323338b0dedb.png" width="500"/> </div><br>
|
<div align="center"> <img src="../pics//cc7bfdeb-452e-4fae-9bc8-323338b0dedb.png" width="400"/> </div><br>
|
||||||
|
|
||||||
<font size=4> **1. 数组实现** </font></br>
|
<font size=4> **1. 数组实现** </font></br>
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ public class Stack<Item> {
|
||||||
|
|
||||||
first-in-first-out(FIFO)
|
first-in-first-out(FIFO)
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//d9efd6bd-3f34-497e-911c-16d5ea38ce88.png" width="500"/> </div><br>
|
<div align="center"> <img src="../pics//d9efd6bd-3f34-497e-911c-16d5ea38ce88.png" width="400"/> </div><br>
|
||||||
|
|
||||||
下面是队列的链表实现,需要维护 first 和 last 节点指针,分别指向队首和队尾。
|
下面是队列的链表实现,需要维护 first 和 last 节点指针,分别指向队首和队尾。
|
||||||
|
|
||||||
|
@ -324,11 +324,11 @@ public class Queue<Item> {
|
||||||
|
|
||||||
用于解决动态连通性问题,能动态连接两个点,并且判断两个点是否连通。
|
用于解决动态连通性问题,能动态连接两个点,并且判断两个点是否连通。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//7e9d0ef2-acd8-44c0-a76b-f0d2f5e76738.png" width="400"/> </div><br>
|
<div align="center"> <img src="../pics//7e9d0ef2-acd8-44c0-a76b-f0d2f5e76738.png" width="300"/> </div><br>
|
||||||
|
|
||||||
<font size=4> **API** </font> <br>
|
<font size=4> **API** </font> <br>
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//867abc3c-8403-43ef-8847-c1fea32996a5.png" width="1000"/> </div><br>
|
<div align="center"> <img src="../pics//867abc3c-8403-43ef-8847-c1fea32996a5.png" width="600"/> </div><br>
|
||||||
|
|
||||||
<font size=4> **基本数据结构** </font> <br>
|
<font size=4> **基本数据结构** </font> <br>
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ public class UF {
|
||||||
|
|
||||||
在 union 时只将节点的 id 值指向另一个节点 id 值,不直接用 id 来存储所属的连通分量。这样就构成一个倒置的树形结构,应该注意的是根节点需要指向自己。查找一个节点所属的连通分量时,要一直向上查找直到根节点,并使用根节点的 id 值作为本连通分量的 id 值。
|
在 union 时只将节点的 id 值指向另一个节点 id 值,不直接用 id 来存储所属的连通分量。这样就构成一个倒置的树形结构,应该注意的是根节点需要指向自己。查找一个节点所属的连通分量时,要一直向上查找直到根节点,并使用根节点的 id 值作为本连通分量的 id 值。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//ae1f3f27-cb47-436d-b8a2-185618851b57.png" width="800"/> </div><br>
|
<div align="center"> <img src="../pics//ae1f3f27-cb47-436d-b8a2-185618851b57.png" width="600"/> </div><br>
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public int find(int p) {
|
public int find(int p) {
|
||||||
|
@ -448,7 +448,7 @@ public class WeightedQuickUnionUF {
|
||||||
|
|
||||||
## 各种 union-find 算法的比较
|
## 各种 union-find 算法的比较
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//cae894a9-2424-4de4-ab41-c15d7054a5e7.png" width="1000"/> </div><br>
|
<div align="center"> <img src="../pics//cae894a9-2424-4de4-ab41-c15d7054a5e7.png" width="800"/> </div><br>
|
||||||
|
|
||||||
# 四、排序
|
# 四、排序
|
||||||
|
|
||||||
|
@ -476,7 +476,7 @@ private void exch(Comparable[] a, int i, int j){
|
||||||
|
|
||||||
找到数组中的最小元素,将它与数组的第一个元素交换位置。再从剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。不断进行这样的操作,直到将整个数组排序。
|
找到数组中的最小元素,将它与数组的第一个元素交换位置。再从剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。不断进行这样的操作,直到将整个数组排序。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//aa62b91f-3540-4a28-8ea9-045f62ab3bcc.png" width="800"/> </div><br>
|
<div align="center"> <img src="../pics//aa62b91f-3540-4a28-8ea9-045f62ab3bcc.png" width="600"/> </div><br>
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public class Selection {
|
public class Selection {
|
||||||
|
@ -499,7 +499,7 @@ public class Selection {
|
||||||
|
|
||||||
插入排序从左到右进行,每次都将当前元素插入到左部已经排序的数组中,使得插入之后左部数组依然有序。
|
插入排序从左到右进行,每次都将当前元素插入到左部已经排序的数组中,使得插入之后左部数组依然有序。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//a451b523-7e24-4fae-8e35-c46b14beed68.png" width="800"/> </div><br>
|
<div align="center"> <img src="../pics//a451b523-7e24-4fae-8e35-c46b14beed68.png" width="600"/> </div><br>
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public class Insertion {
|
public class Insertion {
|
||||||
|
@ -530,9 +530,9 @@ public class Insertion {
|
||||||
|
|
||||||
希尔排序使用插入排序对间隔 h 的序列进行排序,如果 h 很大,那么元素就能很快的移到很远的地方。通过不断减小 h,最后令 h=1,就可以使得整个数组是有序的。
|
希尔排序使用插入排序对间隔 h 的序列进行排序,如果 h 很大,那么元素就能很快的移到很远的地方。通过不断减小 h,最后令 h=1,就可以使得整个数组是有序的。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//bed9d745-f971-405d-ba57-bcfa7986c8bd.png" width="600"/> </div><br>
|
<div align="center"> <img src="../pics//bed9d745-f971-405d-ba57-bcfa7986c8bd.png" width="500"/> </div><br>
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//6e8f16d1-7dea-4331-aea0-3dd739db00a4.png" width="800"/> </div><br>
|
<div align="center"> <img src="../pics//6e8f16d1-7dea-4331-aea0-3dd739db00a4.png" width="600"/> </div><br>
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public class Shell {
|
public class Shell {
|
||||||
|
@ -560,7 +560,7 @@ public class Shell {
|
||||||
|
|
||||||
归并排序的思想是将数组分成两部分,分别进行排序,然后归并起来。
|
归并排序的思想是将数组分成两部分,分别进行排序,然后归并起来。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//8d13ee52-e881-41eb-ad70-678c411f2718.png" width="800"/> </div><br>
|
<div align="center"> <img src="../pics//8d13ee52-e881-41eb-ad70-678c411f2718.png" width="600"/> </div><br>
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//b5fed547-a989-4ead-81d5-ea72660faf99.png" width="800"/> </div><br>
|
<div align="center"> <img src="../pics//b5fed547-a989-4ead-81d5-ea72660faf99.png" width="800"/> </div><br>
|
||||||
|
|
||||||
|
@ -591,7 +591,7 @@ public class MergeSort {
|
||||||
|
|
||||||
### 2. 自顶向下归并排序
|
### 2. 自顶向下归并排序
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//c95a18ae-4b97-4fa9-9806-d9ed7b345b42.png" width="1000"/> </div><br>
|
<div align="center"> <img src="../pics//c95a18ae-4b97-4fa9-9806-d9ed7b345b42.png" width="800"/> </div><br>
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public static void sort(Comparable[] a) {
|
public static void sort(Comparable[] a) {
|
||||||
|
@ -616,7 +616,7 @@ private static void sort(Comparable[] a, int lo, int hi) {
|
||||||
|
|
||||||
先归并那些微型数组,然后成对归并得到的子数组。
|
先归并那些微型数组,然后成对归并得到的子数组。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//4e3faf22-fa80-445e-a57d-594c37bb76e7.png" width="1000"/> </div><br>
|
<div align="center"> <img src="../pics//4e3faf22-fa80-445e-a57d-594c37bb76e7.png" width="800"/> </div><br>
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public static void busort(Comparable[] a) {
|
public static void busort(Comparable[] a) {
|
||||||
|
@ -729,7 +729,7 @@ public class Quick3Way {
|
||||||
|
|
||||||
堆可以用数组来表示,因为堆是一种完全二叉树,而完全二叉树很容易就存储在数组中。位置 k 的节点的父节点位置为 k/2,而它的两个子节点的位置分别为 2k 和 2k+1。这里我们不使用数组索引为 0 的位置,是为了更清晰地理解节点的关系。
|
堆可以用数组来表示,因为堆是一种完全二叉树,而完全二叉树很容易就存储在数组中。位置 k 的节点的父节点位置为 k/2,而它的两个子节点的位置分别为 2k 和 2k+1。这里我们不使用数组索引为 0 的位置,是为了更清晰地理解节点的关系。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//a9b6c1db-0f4a-4e91-8ac8-6b19bd106b51.png" width=""/> </div><br>
|
<div align="center"> <img src="../pics//5144a411-0e46-4a84-a179-c9ad3240418f.png" width="400"/> </div><br>
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public class MaxPQ<Key extends Comparable<Key> {
|
public class MaxPQ<Key extends Comparable<Key> {
|
||||||
|
@ -764,6 +764,8 @@ public class MaxPQ<Key extends Comparable<Key> {
|
||||||
|
|
||||||
在堆中,当一个节点比父节点大,那么需要交换这个两个节点。交换后还可能比它新的父节点大,因此需要不断地进行比较和交换操作。把这种操作称为上浮。
|
在堆中,当一个节点比父节点大,那么需要交换这个两个节点。交换后还可能比它新的父节点大,因此需要不断地进行比较和交换操作。把这种操作称为上浮。
|
||||||
|
|
||||||
|
<div align="center"> <img src="../pics//d5659bcf-5ddf-4692-bfe5-f6b480479120.png" width="400"/> </div><br>
|
||||||
|
|
||||||
```java
|
```java
|
||||||
private void swim(int k) {
|
private void swim(int k) {
|
||||||
while (k > 1 && less(k / 2, k)) {
|
while (k > 1 && less(k / 2, k)) {
|
||||||
|
@ -775,6 +777,8 @@ private void swim(int k) {
|
||||||
|
|
||||||
类似地,当一个节点比子节点来得小,也需要不断的向下比较和交换操作,把这种操作称为下沉。一个节点有两个子节点,应当与两个子节点中最大那么节点进行交换。
|
类似地,当一个节点比子节点来得小,也需要不断的向下比较和交换操作,把这种操作称为下沉。一个节点有两个子节点,应当与两个子节点中最大那么节点进行交换。
|
||||||
|
|
||||||
|
<div align="center"> <img src="../pics//df648536-a107-48cd-a615-77b7a9b4025f.png" width="350"/> </div><br>
|
||||||
|
|
||||||
```java
|
```java
|
||||||
private void sink(int k) {
|
private void sink(int k) {
|
||||||
while (2 * k <= N) {
|
while (2 * k <= N) {
|
||||||
|
@ -820,7 +824,7 @@ public Key delMax() {
|
||||||
|
|
||||||
无序数组建立堆最直接的方法是从左到右遍历数组,然后进行上浮操作。一个更高效的方法是从右至左进行下沉操作,如果一个节点的两个节点都已经是堆有序,那么进行下沉操作可以使得这个节点为根节点的堆有序。叶子节点不需要进行下沉操作,因此可以忽略叶子节点的元素,因此只需要遍历一半的元素即可。
|
无序数组建立堆最直接的方法是从左到右遍历数组,然后进行上浮操作。一个更高效的方法是从右至左进行下沉操作,如果一个节点的两个节点都已经是堆有序,那么进行下沉操作可以使得这个节点为根节点的堆有序。叶子节点不需要进行下沉操作,因此可以忽略叶子节点的元素,因此只需要遍历一半的元素即可。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//a2670745-a7b1-497b-90a4-dbddc4e2006d.jpg" width=""/> </div><br>
|
<div align="center"> <img src="../pics//750501be-6b8a-4cb5-a807-371a218ee612.png" width="800"/> </div><br>
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public static void sort(Comparable[] a){
|
public static void sort(Comparable[] a){
|
||||||
|
@ -849,9 +853,9 @@ public static void sort(Comparable[] a){
|
||||||
|
|
||||||
### 1. 排序算法的比较
|
### 1. 排序算法的比较
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//e4ca3383-910a-4936-8ac2-9e8fd31b736b.png" width="1000"/> </div><br>
|
<div align="center"> <img src="../pics//e4ca3383-910a-4936-8ac2-9e8fd31b736b.png" width="800"/> </div><br>
|
||||||
|
|
||||||
快速排序时最快的通用排序算法,它的内循环的指令很少,而且它还能利用缓存,因为它总是顺序地访问数据。它的运行时间增长数量级为 \~cNlogN,这里的 c 比其他线性对数级别的排序算法都要小。使用三向切分之后,实际应用中可能出现的某些分布的输入能够达到线性级别,而其它排序算法仍然需要线性对数时间。
|
快速排序时最快的通用排序算法,它的内循环的指令很少,而且它还能利用缓存,因为它总是顺序地访问数据。它的运行时间近似为 \~cNlogN,这里的 c 比其他线性对数级别的排序算法都要小。使用三向切分之后,实际应用中可能出现的某些分布的输入能够达到线性级别,而其它排序算法仍然需要线性对数时间。
|
||||||
|
|
||||||
### 2. Java 的排序算法实现
|
### 2. Java 的排序算法实现
|
||||||
|
|
||||||
|
@ -886,11 +890,11 @@ public static Comparable select(Comparable[] a, int k) {
|
||||||
|
|
||||||
### 1. 无序符号表
|
### 1. 无序符号表
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//8a116e69-3d57-4987-a215-0197dd044a14.png" width="800"/> </div><br>
|
<div align="center"> <img src="../pics//8a116e69-3d57-4987-a215-0197dd044a14.png" width="600"/> </div><br>
|
||||||
|
|
||||||
### 2. 有序符号表
|
### 2. 有序符号表
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//299a8cd3-7cfa-45d0-8821-4aa577de4692.png" width="800"/> </div><br>
|
<div align="center"> <img src="../pics//299a8cd3-7cfa-45d0-8821-4aa577de4692.png" width="600"/> </div><br>
|
||||||
|
|
||||||
有序指的是支持 min() max() 等根据键的大小关系来实现的操作。
|
有序指的是支持 min() max() 等根据键的大小关系来实现的操作。
|
||||||
|
|
||||||
|
@ -969,11 +973,11 @@ public class BinarySearchST<Key extends Comparable<Key>, Value> {
|
||||||
|
|
||||||
**二叉查找树** (BST)是一颗二叉树,并且每个节点的值都大于其左子树中的所有节点的值而小于右子树的所有节点的值。
|
**二叉查找树** (BST)是一颗二叉树,并且每个节点的值都大于其左子树中的所有节点的值而小于右子树的所有节点的值。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//1c012d74-6b9d-4f25-a016-7ad4f1f1521898780376.png" width="500"/> </div><br>
|
<div align="center"> <img src="../pics//1c012d74-6b9d-4f25-a016-7ad4f1f1521898780376.png" width="400"/> </div><br>
|
||||||
|
|
||||||
BST 有一个重要性质,就是它的前序遍历结果递增排序。
|
BST 有一个重要性质,就是它的前序遍历结果递增排序。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//5c0bb285-b917-446b-84a2-9810ee41521898714517.png" width="400"/> </div><br>
|
<div align="center"> <img src="../pics//5c0bb285-b917-446b-84a2-9810ee41521898714517.png" width="300"/> </div><br>
|
||||||
|
|
||||||
基本数据结构:
|
基本数据结构:
|
||||||
|
|
||||||
|
|
BIN
pics/5144a411-0e46-4a84-a179-c9ad3240418f.png
Normal file
BIN
pics/5144a411-0e46-4a84-a179-c9ad3240418f.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
BIN
pics/750501be-6b8a-4cb5-a807-371a218ee612.png
Normal file
BIN
pics/750501be-6b8a-4cb5-a807-371a218ee612.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 463 KiB |
BIN
pics/d5659bcf-5ddf-4692-bfe5-f6b480479120.png
Normal file
BIN
pics/d5659bcf-5ddf-4692-bfe5-f6b480479120.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 114 KiB |
BIN
pics/df648536-a107-48cd-a615-77b7a9b4025f.png
Normal file
BIN
pics/df648536-a107-48cd-a615-77b7a9b4025f.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 172 KiB |
Loading…
Reference in New Issue
Block a user