Skip to content

Commit

Permalink
fix: optimize formula latex format
Browse files Browse the repository at this point in the history
  • Loading branch information
HarleysZhang committed Dec 3, 2022
1 parent 48617fb commit 5d665d6
Showing 1 changed file with 15 additions and 15 deletions.
30 changes: 15 additions & 15 deletions 3-data_structure-algorithm/sort/排序.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void bubbleSort(int array[], int n){

**冒泡排序的特点**

1. 冒泡过程只涉及相邻元素的交换,只需要常量级的临时空间,故空间复杂度为 O(1),是**原地排序算法**
1. 冒泡过程只涉及相邻元素的交换,只需要常量级的临时空间,故空间复杂度为 $O(1)$,是**原地排序算法**
2. 当有相邻的两个元素大小相等的时候,我们不做交换,相同大小的数据在排序前后不会改变顺序,所以是**稳定排序算法**
3. 最坏情况和平均时间复杂度都为 $O(n^2)$,最好时间复杂度是 $O(n)$。

Expand Down Expand Up @@ -82,15 +82,15 @@ void InsertSort(int a[], int n){
插入排序的特点:
1. 插入排序并不需要额外存储空间,空间复杂度是 O(1),所以插入排序也是一个原地排序算法。
1. 插入排序并不需要额外存储空间,空间复杂度是 $O(1)$,所以插入排序也是一个原地排序算法。
2. 在插入排序中,对于值相同的元素,我们可以选择将后面出现的元素,插入到前面出现元素的后面,这样就可以保持原有的前后顺序不变,所以插入排序是稳定的排序算法。
3. 最坏情况和平均时间复杂度都为 $O(n^2)$,最好时间复杂度是 $O(n)$。
### 三,选择排序(Selection Sort)
选择排序算法的实现思路有点类似插入排序,也分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。
选择排序的最好情况时间复杂度、最坏情况和平均情况时间复杂度都为 O(n2),是原地排序算法,且是**不稳定的排序算法**。
选择排序的最好情况时间复杂度、最坏情况和平均情况时间复杂度都为 $O(n^2)$,是原地排序算法,且是**不稳定的排序算法**。
选择排序的 `C++` 代码实现如下:
Expand All @@ -115,7 +115,7 @@ void SelectSort(int a[], int n){

![冒泡插入选择排序总结](../data/../../data/images/sort1.png)

这三种排序算法,实现代码都非常简单,对于小规模数据的排序,用起来非常高效。但是在大规模数据排序的时候,这个时间复杂度还是稍微有点高,所以更倾向于用时间复杂度为 O(nlogn) 的排序算法。
这三种排序算法,实现代码都非常简单,对于小规模数据的排序,用起来非常高效。但是在大规模数据排序的时候,这个时间复杂度还是稍微有点高,所以更倾向于用时间复杂度为 $O(nlogn)$ 的排序算法。

特定算法是依赖特定的数据结构的。以上三种排序算法,都是基于数组实现的。

Expand Down Expand Up @@ -166,17 +166,17 @@ merge_sort_c(A, p, r){
$$T(n) = 2*T(n/2) + n; \;n>1$$
$$ \begin{aligned}
T(n) &= 2*T(n/2) + n
\\ &= 2*(2*T(n/4) + n/2) + n = 4*T(n/4) + 2*n
\\ &= 4*(2*T(n/8) + n/4) + 2*n = 8*T(n/8) + 3*n
\\ &= 8*(2*T(n/16) + n/8) + 3*n = 16*T(n/16) + 4*n
\\ &......
\\ &= 2^k * T(n/2^k) + k * n
\\ &......
\end{aligned}$$
一步步分解推导可得 $T(n)= 2^k *T(n/2^k) + k* n$ 。当 $T(n/2^k)=T(1)$ 时,也就是 $n/2^k=1$,我们得到 $k=log2n$ 。我们将 $k$ 值代入上面的公式,得到 $T(n)=Cn+nlog2n$ 。如果我们用大 O 标记法来表示的话,$T(n)$ 就等于 $O(nlogn)$。所以归并排序的时间复杂度是 O(nlogn)。
$$\begin{aligned}
T(n) &= 2*T(n/2) + n \\
&= 2*(2*T(n/4) + n/2) + n = 4*T(n/4) + 2*n \\
&= 4*(2*T(n/8) + n/4) + 2*n = 8*T(n/8) + 3*n \\
&= 8*(2*T(n/16) + n/8) + 3*n = 16*T(n/16) + 4*n \\
&...... \\
&= 2^k * T(n/2^k) + k * n \\
&......
\end{aligned}$$
一步步分解推导可得 $T(n)= 2^k *T(n/2^k) + k* n$ 。当 $T(n/2^k)=T(1)$ 时,也就是 $n/2^k=1$,我们得到 $k=log2n$ 。我们将 $k$ 值代入上面的公式,得到 $T(n)=Cn+nlog2n$ 。如果我们用大 O 标记法来表示的话,$T(n)$ 就等于 $O(nlogn)$。所以归并排序的时间复杂度是 $O(nlogn)$
3,**空间复杂度是 O(n)**。分析:递归代码的空间复杂度并不能像时间复杂度那样累加。尽管算法的每次合并操作都需要申请额外的内存空间,但在合并完成之后,临时开辟的内存空间就被释放掉了。在任意时刻,CPU 只会有一个函数在执行,也就只会有一个临时的内存空间在使用。临时内存空间最大也不会超过 n 个数据的大小,所以空间复杂度是 $O(n)$。
Expand Down

0 comments on commit 5d665d6

Please sign in to comment.