Skip to content

Commit

Permalink
更改节标题
Browse files Browse the repository at this point in the history
  • Loading branch information
itcharge committed Jan 7, 2022
1 parent e1347c1 commit 54db86c
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 51 deletions.
10 changes: 5 additions & 5 deletions Contents/01.Array/02.Array-Sort/01.Array-Bubble-Sort.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
## 1. 算法思想
## 1. 冒泡排序算法思想

> 冒泡排序(Bubble Sort)基本思想:
>
> `i (i = 1,2,… )` 趟排序时从序列中前 `n - i + 1` 个元素的第 `1` 个元素开始,相邻两个元素进行比较,若前者大于后者,两者交换位置,否则不交换。
冒泡排序法是通过相邻元素之间的比较与交换,使值较小的元素逐步从后面移到前面,值较大的元素从前面移到后面,就像水底的气泡一样向上冒,故称这种排序方法为冒泡排序法。

## 2. 算法步骤
## 2. 冒泡排序算法步骤

- 先将序列中第 `1` 个元素与第 `2` 个元素进行比较,若前者大于后者,则两者交换位置,否则不交换;
- 然后将第 `2` 个元素与第 `3` 个元素比较,若前者大于后者,则两者交换位置,否则不交换;
- 依次类推,直到第 `n - 1` 个元素与第 `n` 个元素比较(或交换)为止。经过如此一趟排序,使得 `n` 个元素中值最大元素被安置在序列的第 `n` 个位置上。
- 此后,再对前 `n - 1` 个元素进行同样过程,使得该 `n - 1` 个元素中值最大元素被安置在第 `n - 1` 个位置上。
- 然后再对前 `n - 2` 个元素重复上述过程,直到某一趟排序过程中不出现元素交换位置的动作,排序结束。

## 3. 动画演示
## 3. 冒泡排序动画演示

![img](https://www.runoob.com/wp-content/uploads/2019/03/bubbleSort.gif)

## 4. 算法分析
## 4. 冒泡排序算法分析

- 最好的情况下,初始时序列已经是从小到大有序(升序),则只需经过一趟 `n - 1` 次元素之间的比较,并且不移动元素,算法就可结束排序。此时,算法的时间复杂度为 $O(n)$。
- 最差的情况是当参加排序的初始序列为逆序,或者最小值元素处在序列的最后时,则需要进行 `n - 1` 趟排序,总共进行 $∑^n_{i=2}(i−1) = \frac{n(n−1)}{2}$ 次元素之间的比较,因此,冒泡排序算法的平均时间复杂度为 $O(n^2)$。
- 冒泡排序方法在排序过程中需要移动较多次数的元素。因此,冒泡排序方法比较适合于参加排序序列的数据量较小的情况,尤其是当序列的初始状态为基本有序的情况;而对于一般情况,这种方法是排序时间效率最低的一种方法。
- 由于元素交换是在相邻元素之间进行的,不会改变值相同元素的相对位置,因此,冒泡排序法是一种 **稳定排序法**

## 5. 代码实现
## 5. 冒泡排序代码实现

```Python
class Solution:
Expand Down
10 changes: 5 additions & 5 deletions Contents/01.Array/02.Array-Sort/02.Array-Selection-Sort.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
## 1. 算法思想
## 1. 选择排序算法思想

> 选择排序(Selection Sort)基本思想:
>
> `i` 趟排序从序列的后 `n − i + 1 (i = 1, 2, …, n − 1)` 个元素中选择一个值最小的元素与该 `n - i + 1` 个元素的最前面那个元素交换位置,即与整个序列的第 `i` 个位置上的元素交换位置。如此下去,直到 `i == n − 1`,排序结束。
可以简述为:每一趟排序中,从剩余未排序元素中选择一个最小的元素,与未排好序的元素最前面的那个元素交换位置。

## 2. 算法步骤
## 2. 选择排序算法步骤

- 在算法中设置整型变量 `i`,既可以作为排序趟数的计算,同时也作为执行第 `i` 趟排序时,参加排序的后 `n − i + 1` 个元素的第 `1` 个元素的位置。
- 整型变量 `min_i` 记录这 `n − i + 1` 个元素中值最小元素的位置。
- 每一趟排序开始,先另 `min_i = i` (即暂时假设序列的第 `i` 个元素为值最小者,以后经过比较后视实际情况再正式确定最小值元素的位置)。
-`i` 趟排序比较结束时,这 `n − i + 1` 个元素中真正的值最小元素为下标 `min_i` 对应的元素。此时,若有 `min_i == i`,说明值最小元素就是这 `n − i + 1` 个元素的第 `1` 个元素,意味着此趟排序不必进行元素交换。

## 3. 动画演示
## 3. 选择排序动画演示

![](https://www.runoob.com/wp-content/uploads/2019/03/selectionSort.gif)

## 4. 算法分析
## 4. 选择排序算法分析

对于具有 `n` 个元素的序列采用选择排序方法要经过 `n - 1` 趟排序。

Expand All @@ -26,7 +26,7 @@
- 这说明选择排序法所进行的元素之间的比较次数与序列的原始状态无关,同时可以确定算法的时间复杂度为 $O(n^2)$。
- 由于值最小元素与未排好序的元素中第 `1` 个元素的交换动作是在不相邻的元素之间进行的,因此很有可能会改变值相同元素的前后位置,因此,选择排序法是一种不稳定的排序方法。

## 5. 代码实现
## 5. 选择排序代码实现

```Python
class Solution:
Expand Down
10 changes: 5 additions & 5 deletions Contents/01.Array/02.Array-Sort/03.Array-Insertion-Sort.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
## 1. 算法思想
## 1. 插入排序算法思想

> 插入排序(Insertion Sort)基本思想:
>
> 将整个序列切分为两部分:前 `i - 1` 个元素是有序序列,后 `n - i + 1` 个元素是无序序列。每一次排序,将无序序列的首元素,在有序序列中找到相应的位置并插入。
可以简述为:每一趟排序中,将剩余无序序列的第一个元素,插入到有序序列的适当位置上。

## 2. 算法步骤
## 2. 插入排序算法步骤

- 将第一个元素作为一个有序序列,将第 `2 ~ n - 1` 个元素作为无序序列。
- 从头至尾一次扫描无序序列,将扫描到的每个元素插入到有序序列的适当位置上。

## 3. 动画演示
## 3. 插入排序动画演示

![img](https://www.runoob.com/wp-content/uploads/2019/03/insertionSort.gif)

## 4. 算法分析
## 4. 插入排序算法分析

- 对于具有 `n` 个元素的序列,插入排序方法一共要进行 `n - 1` 趟排序。
- 对于插入排序算法,整个排序过程只需要一个辅助空间 `temp`
Expand All @@ -24,7 +24,7 @@
- 如果序列的初始情况是随机的,即参加排序的序列中元素可能出现的各种排列的概率相同,则可取上述最小值和最大值的平均值作为插入排序时所进行的元素之间的比较次数,约为 $n^2/4$。由此得知,插入排序算法的时间复杂度 $O(n^2)$。
- 插入排序方法属于稳定性排序方法。

## 5. 代码实现
## 5. 插入排序代码实现

```Python
class Solution:
Expand Down
10 changes: 5 additions & 5 deletions Contents/01.Array/02.Array-Sort/04.Array-Shell-Sort.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
## 1. 算法思想
## 1. 希尔排序算法思想

> 希尔排序(Shell Sort)基本思想:
>
> 将整个序列切按照一定的间隔取值划分为若干个子序列,每个子序列分别进行插入排序。然后逐渐缩小间隔进行下一轮划分子序列和插入排序。直至最后一轮排序间隔为 `1`,对整个序列进行插入排序。
>
## 2. 算法步骤
## 2. 希尔排序算法步骤

- 首先确定一个元素间隔数 `gap`,然后将参加排序的序列按此间隔数从第 `1` 个元素开始一次分成若干个子序列,即分别将所有位置相隔为 `gap` 的元素视为一个子序列,在各个子序列中采用某种排序方法进行插入排序。
- 然后减少间隔数,并重新将整个序列按新的间隔数分成若干个子序列,再分别对各个子序列进行排序,如此下去,直到间隔数 `gap = 1`

## 3. 图解演示
## 3. 希尔排序图解演示

![](https://qcdn.itcharge.cn/images/20211019133645.png)

## 4. 算法分析
## 4. 希尔排序算法分析

- 希尔排序方法的速度是一系列间隔数 $gap_i$ 的函数,不太容易弄清楚比较次数与 `gap` 之间的依赖关系,并给出完整的数学分析。
- 上面算法中,由于采用 $gap_i = \lfloor gap_{i-1}/2 \rfloor$ 的方法缩小间隔数,对于具有 `n` 个元素的序列,若 $gap_1 = \lfloor n/2 \rfloor$,则经过 $p = \lfloor log_2 n \rfloor$ 趟排序后就有 $gap_p = 1$,因此,希尔排序方法的排序总躺数为 $\lfloor log_2 n \rfloor$。
- 从算法中也可以看到,最外层的 while 循环为 $log_2 n$ 数量级,中间层 do-while 循环为 `n` 数量级。当子序列分得越多时,子序列内的元素就越少,最内层的 for 循环的次数也就越少;反之,当所分的子序列个数减少时,子序列内的元素也随之增多,但整个序列也逐步接近有序,而循环次数却不会随之增加。因此,希尔排序算法的时间复杂度在 $O(n log_2 n)$ 与 $O(n^2)$ 之间。
- 希尔排序方法是一种不稳定排序算法。

## 5. 代码实现
## 5. 希尔排序代码实现

```Python
class Solution:
Expand Down
10 changes: 5 additions & 5 deletions Contents/01.Array/02.Array-Sort/05.Array-Merge-Sort.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
## 1. 算法思想
## 1. 归并排序算法思想

> 归并排序(Merge Sort)基本思想:
>
> 采用经典的分治策略,先递归地将当前序列平均分成两半。然后将有序序列两两合并,最终合并成一个有序序列。
## 2. 算法步骤
## 2. 归并排序算法步骤

- 初始时,将待排序序列中的 `n` 个记录看成 `n` 个有序子序列(每个子序列总是有序的),每个子序列的长度均为 `1`
- 把当前序列组中有序子序列两两归并,完成一遍之后序列组里的排序序列个数减半,每个子序列的长度加倍。
- 对长度加倍的有序子序列重复上面的操作,最终得到一个长度为 `n` 的有序序列。

## 3. 动画演示
## 3. 归并排序动画演示

![](https://www.runoob.com/wp-content/uploads/2019/03/mergeSort.gif)

## 4. 算法分析
## 4. 归并排序算法分析

- 归并排序算法的时间复杂度等于归并趟数与每一趟归并的时间复杂度成绩。子算法 `merge(left_arr, right_arr):` 的时间复杂度是 $O(n)$,因此,归并排序算法总的时间复杂度为 $O(nlog_2n)$。
- 归并排序方法需要用到与参加排序的序列同样大小的辅助空间。因此算法的空间复杂度为 $O(n)$。
- 因为在两个有序子序列的归并过程中,如果两个有序序列中出现相同元素,`merge(left_arr, right_arr):` 算法能够使前一个序列中那个相同元素先被复制,从而确保这两个元素的相对次序不发生改变。所以归并排序算法是 **稳定排序算法**

## 5. 代码实现
## 5. 归并排序代码实现

```Python
class Solution:
Expand Down
10 changes: 5 additions & 5 deletions Contents/01.Array/02.Array-Sort/06.Array-Quick-Sort.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
## 1. 算法思想
## 1. 快速排序算法思想

> 快速排序(Quick Sort)基本思想:
>
> 通过一趟排序将无序序列分为独立的两个序列,第一个序列的值均比第二个序列的值小。然后递归地排列两个子序列,以达到整个序列有序。
## 2. 算法步骤
## 2. 快速排序算法步骤

- 从数组中找到一个基准数。
- 然后将数组中比基准数大的元素移动到基准数右侧,比他小的元素移动到基准数左侧,从而把数组拆分为左右两个部分。
- 再对左右两个部分分别重复第二步,直到各个部分只有一个数,则排序结束。

## 3. 动画演示
## 3. 快速排序动画演示

![](https://www.runoob.com/wp-content/uploads/2019/03/quickSort.gif)

## 4. 算法分析
## 4. 快速排序算法分析

- 在参加排序的元素初始时已经有序的情况下,快速排序方法花费的时间最长。此时,第 `1` 趟排序经过 `n - 1` 次比较以后,将第 `1` 个元素仍然确定在原来的位置上,并得到 `1` 个长度为 `n - 1` 的子序列;第 `2` 趟排序进过 `n - 2` 次比较以后,将第 `2` 个元素确定在它原来的位置上,又得到 `1` 个长度为 `n - 2` 的子序列;依次类推,最终总的比较次数为 $(n − 1) + (n − 2) + … + 1 = \frac{n(n − 1)}{2}$。因此时间复杂度为 $O(n^2)$。

Expand All @@ -30,7 +30,7 @@

- 快速排序时一种 **不稳定排序算法**,也是一种不适合在链表结构上实现的排序算法。

## 5. 代码实现
## 5. 快速排序代码实现

```Python
import random
Expand Down
12 changes: 6 additions & 6 deletions Contents/01.Array/02.Array-Sort/07.Array-Heap-Sort.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
## 1. 算法思想
## 1. 堆排序算法思想

> 堆排序(Heap sort)基本思想:
>
> 借用「堆结构」所设计的排序算法。将数组转化为大顶堆,重复从大顶堆中取出数值最大的节点,并让剩余的堆维持大顶堆性质。
## 1.1 堆的定义
### 1.1 堆的定义

堆:符合以下两个条件之一的完全二叉树:

- 大顶堆:根节点值 ≥ 子节点值。
- 小顶堆:根节点值 ≤ 子节点值。

## 2. 算法步骤
## 2. 堆排序算法步骤

- 首先将无序序列构造成第 `1` 个大顶堆(初始堆),使得 `n` 个元素的最大值处于序列的第 `1` 个位置。
- 然后交换序列的第 `1` 个元素(最大值元素)与最后一个元素的位置。
Expand All @@ -33,7 +33,7 @@
- 如果原始序列对应的完全二叉树(不一定是堆)的深度为 `d`,则从 `d - 1` 层最右侧分支节点(序号为 $\lfloor n/2 \rfloor$)开始,初始时令 $i = \lfloor n/2 \rfloor$,调用堆调整算法。
- 每调用一次堆调整算法,执行一次 `i = i - 1`,直到 `i == 1` 时,再调用一次,就把原始序列调整为了一个初始堆。

## 3. 动画演示
## 3. 堆排序动画演示

### 3.1 堆调整方法演示

Expand All @@ -47,7 +47,7 @@

![](http://qcdn.itcharge.cn/images/20211019172547.gif)

## 4. 算法分析
## 4. 堆排序算法分析

- 堆积排序的时间主要花费在两个方面:
- 将原始序列构造为一个初始堆积。
Expand All @@ -60,7 +60,7 @@
- 由于在堆积排序中只需要一个记录大小的辅助空间,因此,堆积排序的空间复杂度为:$O(1)$。
- 堆排序属于 **不稳定排序算法**。堆排序也是一种不适合在链表上实现的排序。

## 5. 代码实现
## 5. 堆排序代码实现

```Python
class Solution:
Expand Down
10 changes: 5 additions & 5 deletions Contents/01.Array/02.Array-Sort/08.Array-Counting-Sort.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
## 1. 算法思想
## 1. 计数排序算法思想

> 计数排序(Counting Sort)基本思想:
>
> 使用一个额外的数组 `counts`,其中第 `i` 个元素 `counts[i]` 是待排序数组 `arr` 中值等于 `i` 的元素个数。然后根据数组 `counts` 来将 `arr` 中的元素排到正确的位置。
## 2. 算法步骤
## 2. 计数排序算法步骤

- 找出待排序数组中最大值元素和最小值元素。
- 统计数组中每个值为 `i` 的元素出现的次数,存入数组的第 `i` 项。
- 对所有的计数累加(从 `counts` 中的第一个元素开始,每一项和前一项累加)。
- 反向填充目标数组:将每个元素 `i` 放在新数组的第 `counts[i]` 项,每放一个元素就要将 `counts[i] -= 1`

## 3. 动画演示
## 3. 计数排序动画演示

![](https://www.runoob.com/wp-content/uploads/2019/03/countingSort.gif)

## 4. 算法分析
## 4. 计数排序算法分析

- 当输入元素是 `n``0 ~ k` 之间的整数时,计数排序的时间复杂度为 $O(n + k)$。
- 由于用于计数的数组 `counts` 的长度取决于待排序数组中数据的范围(等于待排序数组最大值减去最小值再加 `1`)。所以计数排序对于数据范围很大的数组,需要大量的时间和内存。
- 计数排序一般用于排序整数,不适用于按字母顺序排序人名。
- 计数排序是 **稳定排序算法**

## 5. 代码实现
## 5. 计数排序代码实现

```Python
class Solution:
Expand Down
10 changes: 5 additions & 5 deletions Contents/01.Array/02.Array-Sort/09.Array-Bucket-Sort.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
## 1. 算法思想
## 1. 桶排序算法思想

> 桶排序(Bucket Sort)基本思想:
>
> 将未排序的数组分到若干个「桶」中,每个桶的元素再进行单独排序。
## 2. 算法步骤
## 2. 桶排序算法步骤

- 将区间划分为 `n` 个相同大小的子区间,每个区间称为一个桶。
- 遍历数组,将每个元素装入对应的桶中。
- 对每个桶内的元素单独排序(使用插入、归并、快排等算法)。
- 最后按照顺序将桶内的元素合并起来。

## 3. 图解演示
## 3. 桶排序图解演示

### 3.1 划分子区间

Expand All @@ -25,13 +25,13 @@

![](https://qcdn.itcharge.cn/images/20211020155335.png)

## 4. 算法分析
## 4. 桶排序算法分析

- 桶排序可以在线性时间内完成排序,当输入元素个数为 `n`,桶的个数是 `m` 时,桶排序时间复杂度为 $O(n + m)$。
- 由于桶排序使用了辅助空间,所以桶排序的空间复杂度是 `o(n + m)`
- 如果桶内使用插入排序算法等稳定排序算法,则桶排序也是 **稳定排序算法**

## 5. 代码实现
## 5. 桶排序代码实现

```Python
class Solution:
Expand Down
10 changes: 5 additions & 5 deletions Contents/01.Array/02.Array-Sort/10.Array-Radix-Sort.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
## 1. 算法思想
## 1. 基数排序算法思想

> 基数排序(Radix Sort)基本思想:
>
> 将整数按位数切割成不同的数字,然后按每个位数分别比较进行排序。
## 2. 算法步骤
## 2. 基数排序算法步骤

基数排序算法可以采用「最低位优先法(Least Significant Digit First)」或者「最高位优先法(Most Significant Digit first)」。最常用的是「最低位优先法」。

Expand All @@ -15,17 +15,17 @@
- 合并数组。
- 之后依次以十位,百位,…,直到最大值元素的最高位处值为索引,进行排序,并合并数组,最终完成排序。

## 3. 动画演示
## 3. 基数排序动画演示

![](https://www.runoob.com/wp-content/uploads/2019/03/radixSort.gif)

## 4. 算法分析
## 4. 基数排序算法分析

- 基数排序的时间复杂度是 $O(k * n)$。其中 `n` 是待排序元素的个数,`k` 是数字位数。`k` 的大小取决于数字位的选择(十进制位、二进制位)和待排序元素所属数据类型全集的大小。
- 基数排序的空间复杂度是 $O(n + k)$。
- 基数排序是 **稳定排序算法**

## 5. 代码实现
## 5. 基数排序代码实现

```Python
class Solution:
Expand Down

0 comments on commit 54db86c

Please sign in to comment.