Skip to content

Commit

Permalink
冒泡排序内容优化
Browse files Browse the repository at this point in the history
  • Loading branch information
itcharge committed Aug 15, 2023
1 parent 6a9d883 commit 2f213b9
Showing 1 changed file with 41 additions and 33 deletions.
74 changes: 41 additions & 33 deletions Contents/01.Array/02.Array-Sort/01.Array-Bubble-Sort.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,53 @@

> **冒泡排序(Bubble Sort)基本思想**
>
> `i (i = 1, 2, …)` 趟排序时从序列中前 `n - i + 1` 个元素的第 `1` 个元素开始,相邻两个元素进行比较,若前者大于后者,两者交换位置,否则不交换
> 经过多次迭代,通过相邻元素之间的比较与交换,使值较小的元素逐步从后面移到前面,值较大的元素从前面移到后面
简单来说,「冒泡排序法」通过相邻元素之间的比较与交换,使值较小的元素逐步从后面移到前面,值较大的元素从前面移到后面
这个过程就像水底的气泡一样从底部向上「冒泡」到水面,这也是冒泡排序法名字的由来

这个过程就像水底的气泡一样向上冒,这也是冒泡排序法名字的由来。
接下来,我们使用「冒泡」的方式来模拟一下这个过程。

1. 首先将数组想象是一排「泡泡」,元素值的大小与泡泡的大小成正比。
2. 然后从左到右依次比较相邻的两个「泡泡」:
1. 如果左侧泡泡大于右侧泡泡,则交换两个泡泡的位置。
2. 如果左侧泡泡小于等于右侧泡泡,则两个泡泡保持不变。
3. 这 $1$ 趟遍历完成之后,最大的泡泡就会放置到所有泡泡的最右侧,就像是「泡泡」从水底向上浮到了水面。

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

1.`1` 趟排序,从序列中前 `n` 个元素的第 `1` 个元素开始,相邻两个元素依次进行比较和交换:
1. 先将序列中第 `1` 个元素与第 `2` 个元素进行比较,如果前者大于后者,则两者交换位置,否则不交换;
2. 然后将第 `2` 个元素与第 `3` 个元素比较,如果前者大于后者,则两者交换位置,否则不交换;
3. 依次类推,直到第 `n - 1` 个元素与第 `n` 个元素比较(或交换)为止。
4. 经过第 `1` 趟排序,使得 `n` 个元素中第 `i` 个值最大元素被安置在第 `n` 个位置上。
2.`2` 趟排序,从序列中前 `n - 1` 个元素的第 `1` 个元素开始,相邻两个元素依次进行比较和交换:
1. 先将序列中第 `1` 个元素与第 `2` 个元素进行比较,若前者大于后者,则两者交换位置,否则不交换;
2. 然后将第 `2` 个元素与第 `3` 个元素比较,若前者大于后者,则两者交换位置,否则不交换;
3. 依次类推,直到对 `n - 2` 个元素与第 `n - 1` 个元素比较(或交换)为止。
4. 经过第 `2` 趟排序,使得数组中第 `2` 个值最大元素被安置在第 `n - 1` 个位置上。
3. 依次类推,对前 `n - 2` 个元素重复上述排序过程,直到某一趟排序过程中不出现元素交换位置的动作,则排序结束。
假设数组的元素个数为 $n$ 个,则冒泡排序的算法步骤如下:

1. 第 $1$ 趟遍历:对前 $n$ 个元素执行「冒泡」,从而使第 $1$ 个值最大的元素放置在正确位置上。
1. 先将序列中第 $1$ 个元素与第 $2$ 个元素进行比较,如果前者大于后者,则两者交换位置,否则不交换;
2. 然后将第 $2$ 个元素与第 $3$ 个元素比较,如果前者大于后者,则两者交换位置,否则不交换;
3. 依次类推,直到第 $n - 1$ 个元素与第 $n$ 个元素比较(或交换)为止。
4. 经过第 $1$ 趟排序,使得 $n$ 个元素中第 $i$ 个值最大元素被安置在第 $n$ 个位置上。
2. 第 $2$ 趟遍历:对前 $n - 1$ 个元素执行「冒泡」,从而使第 $2$ 个值最大的元素放置在正确位置上:
1. 先将序列中第 $1$ 个元素与第 $2$ 个元素进行比较,若前者大于后者,则两者交换位置,否则不交换;
2. 然后将第 $2$ 个元素与第 $3$ 个元素比较,若前者大于后者,则两者交换位置,否则不交换;
3. 依次类推,直到对 $n - 2$ 个元素与第 $n - 1$ 个元素比较(或交换)为止。
4. 经过第 $2$ 趟排序,使得数组中第 $2$ 个值最大元素被安置在第 $n$ 个位置上。
3. 依次类推,重复上述「冒泡」过程,直到某一趟排序过程中不出现元素交换位置的动作,则排序结束。

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

![](https://qcdn.itcharge.cn/images/20220812131649.gif)

1. 初始序列为:`[6, 2, 3, 5, 1, 4]`
2.`1` 趟排序,从序列中前 `6` 个元素的第 `1` 个元素开始,相邻两个元素进行比较和交换
1. 先将序列中第 `1` 个元素与第 `2` 个元素进行比较,也就是将 `6``2` 进行比较。因为 `6 > 2`,所以两者交换位置,交换位置后,`2` 在第 `1` 位,`6` 在第 `2` 位。
2. 然后将第 `2` 个元素与第 `3` 个元素比较,也就是将 `2``3` 进行比较。因为 `2 < 3`,所以不用交换;
1. 初始序列为:$[6, 2, 3, 5, 1, 4]$
2.$1$ 趟遍历,从序列中前 `6` 个元素的第 $1$ 个元素开始,相邻两个元素进行比较和交换:
1. 先将序列中第 $1$ 个元素与第 $2$ 个元素进行比较,也就是将 `6`$2$ 进行比较。因为 `6 > 2`,所以两者交换位置,交换位置后,$2$ 在第 $1$ 位,`6` 在第 $2$ 位。
2. 然后将第 $2$ 个元素与第 $3$ 个元素比较,也就是将 $2$$3$ 进行比较。因为 `2 < 3`,所以不用交换;
3. 依次类推,直到第 `5` 个元素与第 `6` 个元素比较(或交换)为止。
4. 经过第 `1` 趟排序,使得 `6` 个元素中第 `6` 个值最大元素被安置在第 `6` 个位置上。此时序列变为: `[2, 3, 5, 1, 4, 6]`
3.`2` 趟排序,从序列中前 `5` 个元素的第 `1` 个元素开始,相邻两个元素进行比较和交换
1. 先将序列中第 `1` 个元素与第 `2` 个元素进行比较,也就是将 `2``3` 进行比较。因为 `2 < 3`,所以不用交换;
2. 然后将第 `2` 个元素与第 `3` 个元素比较,也就是将 `3``4` 进行比较。因为 `3 < 5`,所以不用交换;
3. 然后将第 `3` 个元素与第 `4` 个元素比较,也就是将 `5``1` 进行比较。因为 `5 > 1`,所以两者交换位置,交换位置后,`1` 在第 `3` 位,`5` 在第 `4` 位。
4. 经过第 $1$ 趟排序,使得 `6` 个元素中第 `6` 个值最大元素被安置在第 `6` 个位置上。此时序列变为: `[2, 3, 5, 1, 4, 6]`
3.$2$ 趟排序,从序列中前 `5` 个元素的第 $1$ 个元素开始,相邻两个元素进行比较和交换:
1. 先将序列中第 $1$ 个元素与第 $2$ 个元素进行比较,也就是将 $2$$3$ 进行比较。因为 `2 < 3`,所以不用交换;
2. 然后将第 $2$ 个元素与第 $3$ 个元素比较,也就是将 $3$`4` 进行比较。因为 `3 < 5`,所以不用交换;
3. 然后将第 $3$ 个元素与第 `4` 个元素比较,也就是将 `5`$1$ 进行比较。因为 `5 > 1`,所以两者交换位置,交换位置后,$1$ 在第 $3$ 位,`5` 在第 `4` 位。
4. 依次类推,直到第 `4` 个元素与第 `5` 个元素比较(或交换)为止。
5. 经过第 `2` 趟排序,使得 `5` 个元素中第 `5` 个值最大元素被安置在第 `5` 个位置上。此时序列变为: `[2, 3, 1, 4, 5, 6]`
5. 经过第 $2$ 趟排序,使得 `5` 个元素中第 `5` 个值最大元素被安置在第 `5` 个位置上。此时序列变为: `[2, 3, 1, 4, 5, 6]`
4. 依次类推,对前 `4` 个元素重复上述排序过程,直到某一趟排序过程中不出现元素交换位置的动作,则排序结束。此时序列变为:`[1, 2, 3, 4, 5, 6]`

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

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

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

```python
class Solution:
Expand All @@ -64,4 +65,11 @@ class Solution:

def sortArray(self, nums: List[int]) -> List[int]:
return self.bubbleSort(nums)
```
```

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

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

0 comments on commit 2f213b9

Please sign in to comment.