各種排序演算法比較

2021-06-19 04:30:25 字數 3971 閱讀 8359

花了很長時間終於把排序的基礎學了一下,這段時間學了很多東西,總結一下:

學的排序演算法有:插入排序,合併排序,氣泡排序,選擇排序,希爾排序,堆排序,快速排序,計數排序,基數排序,桶排序(沒有實現)。比較一下學習後的心得。

我不是很清楚他們的時間複雜度,也真的不知道他們到底誰快誰慢,因為書上的推導我確實只是小小了解,並沒有消化。也沒有完全理解他們的精髓,所以又什麼錯誤的還需要高手指點。呵呵。

1.普及一下排序穩定,所謂排序穩定就是指:如果兩個數相同,對他們進行的排序結果為他們的相對順序不變。例如a=這裡排序之後是a = 穩定就是排序後第乙個1就是排序前的第乙個1,第二個1就是排序前第二個1,第三個1就是排序前的第三個1。同理2也是一樣。這裡用顏色標明了。不穩定呢就是他們的順序不應和開始順序一致。也就是可能會是a=這樣的結果。

2.普及一下原地排序:原地排序就是指不申請多餘的空間來進行的排序,就是在原來的排序資料中比較和交換的排序。例如快速排序,堆排序等都是原地排序,合併排序,計數排序等不是原地排序。

3.感覺誰最好,在我的印象中快速排序是最好的,時間複雜度:n*log(n),不穩定排序。原地排序。他的名字很棒,快速嘛。當然快了。我覺得他的思想很不錯,分治,而且還是原地排序,省去和很多的空間浪費。速度也是很快的,n*log(n)。但是有乙個軟肋就是如果已經是排好的情況下時間複雜度就是n*n,不過在加入隨機的情況下這種情況也得以好轉,而且他可以做任意的比較,只要你能給出兩個元素的大小關係就可以了。適用範圍廣,速度快。

4.插入排序:n*n的時間複雜度,穩定排序,原地排序。插入排序是我學的第乙個排序,速度還是很快的,特別是在陣列已排好了之後,用它的思想來插入乙個資料,效率是很高的。因為不用全部排。他的資料交換也很少,只是資料後移,然後放入要插入的資料。(這裡不是指呼叫插入排序,而是用它的思想)。我覺得,在資料大部分都排好了,用插入排序會給你帶來很大的方便。資料的移動和交換都很少。

5.氣泡排序,n*n的時間複雜度,穩定排序,原地排序。氣泡排序的思想很不錯,乙個乙個比較,把小的上移,依次確定當前最小元素。因為他簡單,穩定排序,而且好實現,所以用處也是比較多的。還有一點就是加上哨兵之後他可以提前退出。

6.選擇排序,n*n的時間複雜度, 穩定排序,原地排序。選擇排序就是冒泡的基本思想,從小的定位,乙個乙個選擇,直到選擇結束。他和插入排序是乙個相反的過程,插入是確定乙個元素的位置,而選擇是確定這個位置的元素。他的好處就是每次只選擇確定的元素,不會對很多資料進行交換。所以在資料交換量上應該比冒泡小。

8.合併排序:n*log(n)的時間複雜度, 穩定排序,非原地排序。他的思想是分治,先分成小的部分,排好部分之後合併,因為我們另外申請的空間,在合併的時候效率是0(n)的。速度很快。貌似他的上限是n*log(n),所以如果說是比較的次數的話,他比快速排序要少一些。對任意的陣列都能有效地在n*log(n)排好序。但是因為他是非原地排序,所以雖然他很快,但是貌似他的人氣沒有快速排序高。

9.堆排序:n*log(n)的時間複雜度, 非穩定排序,原地排序。他的思想是利用的堆這種資料結構,堆可以看成乙個完全二叉樹,所以在排序中比較的次數可以做到很少。加上他也是原地排序,不需要申請額外的空間,效率也不錯。可是他的思想感覺比快速難掌握一些。還有就是在已經排好序的基礎上新增乙個資料再排序,他的交換次數和比較次數一點都不會減少。雖然堆排序在使用的中沒有快速排序廣泛,但是他的資料結構和思想真的很不錯,而且用它來實現優先佇列,效率沒得說。堆,還是要好好學習掌握的。

10.希爾排序:n*log(n)的時間複雜度(這裡是錯誤的,應該是n^lamda(1 < lamda < 2), lamda和每次步長選擇有關。), 非穩定排序,原地排序。主要思想是分治,不過他的分治和合併排序的分治不一樣,他是按步長來分組的,而不是想合併那樣左一半右一半。開始步長為整個的長度的一半。分成nlen/2個組,然後每組排序。接個步長減為原來的一半在分組排序,直到步長為1,排序之後希爾排序就完成了。這個思路很好,據說是插入排序的公升級版,所以在實現每組排序的時候我故意用了插入排序。我覺得他是乙個特別好的排序方法了。他的缺點就是兩個數可能比較多次,因為兩個資料會多次分不過他們不會出現資料的交換。效率也是很高的。

11.快速排序,堆排序,合併排序,希爾排序的比較,他們的時間複雜的都是n*log(n),我認為在使用上快速排序最廣泛,他原地排序,雖然不穩定,可是很多情況下排序根本就不在意他是否穩定。他的比較次數是比較小的,因為他把資料分成了大和小的兩部分。每次都確定了乙個數的位置,所以理論上說不會出現兩個數比較兩次的情況,也是在最後在交換資料,說以資料交換上也很少。合併排序和堆排序也有這些優點,但是合併排序要申請額外的空間。堆排序堆已經排好的資料交換上比快速多。所以目前快速排序用的要廣泛的多。還有他很容易掌握和實現。

12.計數排序:n的時間複雜度,穩定排序,非原地排序。他的思想比較新穎,就是先約定資料的範圍不是很大,而且資料都是整數(或能定位到整數)的情況,然後直接申請乙個空間。把要排序的陣列a的元素值與申請空間b的下標對應,然後b中存放該下標元素值的個數,從而直接定位a中每個元素的位置。這樣效率只為n。因為比較很特殊,雖然很快,但是用的地方並不多。

13.基數排序:n的時間複雜度,穩定排序,非原地排序。他的思想是資料比較集中在乙個範圍,例如都是4位數,都是5位數,或資料有多個關鍵字,我們先從各位開始排,然後排十位,依次排到最高位,因為我們可以用乙個n的方法排一位,所以總的方法為d*n的複雜度。關鍵字也一樣,我們先排第3個關鍵字,在排第3個關鍵字,最後排第乙個關鍵字。只有能保證每個關鍵字在n的時間複雜度完成,那麼整個排序就是乙個d*n的時間複雜度。所以總的速度是很快的。不過有一點就是要確保關鍵字能在n的時間複雜度完成。

14.桶排序:n的時間複雜度,穩定排序,非原地排序。主要思路和基數排序一樣,也是假設都在乙個範圍例如概率都在0-1,而且分布還挺均勻,那麼我們也是和基數排序一樣對乙個數把他劃分在他指定的區域。然後在連線這些區域就可以了。書上對每個區域使用鍊錶的儲存,我認為在寸小區域的時候也會有時間在裡面。所以只是理論上的n時間複雜度。這種思路是不錯的。呵呵。

15.計數排序,基數排序,桶排序的比較,我覺得他們都很有思想,不過都是在特定情況下才能發揮最大的效果。雖然效率很高,但是用的不會很廣泛。他們之間我更喜歡計數排序,來個對映的方式就直接找到了自己的位置,很高明。和基數排序和同排序只是理論上的n時間複雜度,基數排序要確定乙個關鍵字的排序是n複雜度的,桶排序要確定每個區域的排序是n複雜度的。

16.排序演算法的最後感悟:黑格爾說過:存在即合理。所以這些排序的演算法都是很好的,他確實給了我們思想上的幫助。感謝前人把精華留給了我們。我得到的收穫很大,總結一下各自排序的收穫:

冒泡:好實現,速度不慢,使用於輕量級的資料排序。

插入排序:也使用於小資料的排序,但是我從他的思想中學到怎麼插入乙個資料。呵呵,這樣就知道在排好的資料裡面,不用再排序了,而是直接呼叫一下插入就可以了。

選擇排序:我學會了怎麼去獲得最大值,最小值等方法。只要選擇一下,不就可以了。

合併排序:我學會分而治之的方法,而且在合併兩個陣列的時候很適用。

堆排序:可以用它來實現優先佇列,而且他的思想應該給我加了很多內力。

快速排序:本來就用的最多的排序,對我的幫助大的都不知道怎麼說好。

希爾排序:也是分治,讓我看到了分治的不同,原來還有這種思想的存在。

計數排序,基數排序,桶排序:特殊情況特殊處理。

以上鏈結為:

附乙個排序的動畫: 好牛叉啊!

排序演算法分兩種:

1.比較排序,時間複雜度最少達到o(n*lg n),主要有:插入排序,氣泡排序,選擇排序,合併排序,堆排序,快速排序等。

2.非比較排序,時間複雜度可以達到o(n),主要有:計數排序,基數排序,桶排序等。

平均情況

最好情況

最壞情況

歸併排序

o(nlogn) 

o(nlogn)

o(nlogn)

基數排序

o(n)

o(n)

o(n)

快速排序

o(nlogn)

o(nlogn)

o(n2)

希爾排序

o(n1.5)

o(n)

o(n1.5)

插入排序

o(n2)

o(n)

o(n2)

選擇排序

o(n2)

o(n2)

o(n2)

詳細的效能總結:

各種排序演算法比較

排序相關的演算法複雜度分析 下邊分別實現下各個演算法 簡單選擇排序 1 簡單選擇排序 2void select sort int a,intn 3 16 17swap a i a index 18 19 這裡簡單選擇排序之所以不穩定是因為交換的時候會打亂順序,例如 5,4,5,1,6。第一次交換後會...

各種排序演算法的比較

穩定的排序演算法有 直接插入,冒泡,歸併,基數排序。一.快速排序 快排的三個步驟 1.選取樞紐元,一般用三數中值法,即求得left,center,right的中位數 不要用第乙個數,如果原始資料是倒序,效率將會很低 2.根據樞紐元把輸入資料劃分成為兩部分,左半部分的數比樞紐元小,右半部分比樞紐元大。...

各種排序演算法的比較

排序問題的解決方案是演算法問題當中最多的,常見的有插入排序,選擇排序,氣泡排序,歸併排序,快速排序,堆排序等,下面將對不同的排序演算法進行分析。假設均為實現從小到大排序,計算空間複雜度時,不考慮原本儲存元素的空間,只考慮實現演算法需要的額外空間。插入排序的基本思想是 從待排序的元素中選出乙個,插入已...