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