数据结构与算法 / 排序算法(2)
一、歸并排序
1、原理
? ? ? ?采用分治思想。將數(shù)組分成前后兩部分,先將這兩部分進行排序,然后再將二者合并即可。
2、原地排序?
? ? ? ?不屬于原地排序。因為每次合并都需要申請大小為 n 的臨時數(shù)組用于保存合并之后的結(jié)果,所以空間復(fù)雜度為O(n)。
3、穩(wěn)定性排序?
? ? ? ?屬于穩(wěn)定排序算法。為了達到上述目的,只需要在合并時將前后兩部分相同的元素中的屬于前面部分的數(shù)據(jù)先放入臨時數(shù)組即可。
4、時間復(fù)雜度
? ? ? ?因為代碼采用了遞歸方式,所以這里需要使用遞歸公式來估計時間復(fù)雜度。遞歸公式如下:
? ? ? ?這里的 T(a) 表示單次遞歸時的耗時,T(a1)代表均分之后前一部分的排序時間,T(a2)代表均分之后后一部分的排序時間,t 為二者合并時間。通過代碼發(fā)現(xiàn),合并 n 個數(shù)據(jù),需要比較 n 次,如下圖所示:
故所以 t = n 。?
? ? ? ?對于歸并排序,時間復(fù)雜度的公式:
? ? ? ?經(jīng)過遞推,則公式如下:
? ? ? ?當(dāng)?時,。將 k 代入上述公式中,則結(jié)果為??,這里面的??。所以時間復(fù)雜度為 O(nlogn) 。
二、快速排序
1、原理
? ? ? ?采用分治思想,是優(yōu)化之后的冒泡排序。隨機從數(shù)列找到一個數(shù)作為中心點(pivot),小于該數(shù)的放在左邊,大于該數(shù)的放在右邊,上述操作取名為“分區(qū)”。上述兩部分數(shù)據(jù)在再依次分區(qū),直至數(shù)據(jù)不能再分區(qū)為止,這樣數(shù)據(jù)就變成有序的了。
2、原地排序?
? ? ? 屬于原地排序算法。因為在分區(qū)的過程中,使用了交換數(shù)據(jù)的方法,并沒有建 n 個臨時內(nèi)存,所以空間復(fù)雜度為 O(1) 。
3、穩(wěn)定性排序?
? ? ? 不屬于穩(wěn)定性排序。栗子:
6、7、9、6、3、5? ? ?經(jīng)過排序之后發(fā)現(xiàn),第1個“6”和第2個“6”發(fā)生了位置顛倒,所以該算法不屬于穩(wěn)定性排序算法。
4、時間復(fù)雜度
(1)最好的情況
? ? ? ?每次分區(qū)時選擇的 pivot?均是數(shù)組的中間值,那么時間復(fù)雜度就是 O(nlogn) 。
(2)最壞的情況
? ? ? ?原數(shù)組已經(jīng)有序但是是逆序,例如:102、10、8、5、2,目標是從小到大排序,每次分區(qū)時選擇的 pivot 均是最右面的值,則需要比較 n-1 、n-2、n-3、……、1,那么時間復(fù)雜度的和就是?O(n^2)?。
(3)平均時間復(fù)雜度
? ? ? ?(后續(xù)補充)
三、總結(jié)
1、性質(zhì)
| 算法種類 | 時間復(fù)雜度 | 空間復(fù)雜度 | 原地排序 | 穩(wěn)定排序 |
| 歸并排序 | O(nlogn) | O(n) | × | √ |
| 快速排序 | O(nlogn) | O(1) | √ | × |
2、源碼
Github
?
(SAW:Game Over!)
總結(jié)
以上是生活随笔為你收集整理的数据结构与算法 / 排序算法(2)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cpp 对象模型探索 / 对象的虚函数表
- 下一篇: Cpp 对象模型探索 / 继承关系下的