排序演算法的比較

來源:互聯網
上載者:User

排序演算法有:插入排序,合并排序,冒泡排序,選擇排序,希爾排序,堆排序,快速排序,計數排序,基數排序,桶排序(沒有實現)。

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

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

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

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

【備忘】

1、直接插入排序:

2、折半插入排序:比直接插入排序減少了比較次數,但是移動次數不變。
  冒泡排序,n*n的時間複雜度,穩定排序,原地排序。冒泡排序的思想很不錯,一個一個比較,把小的上移,依次確定當前最小元素。因為他簡單,穩定排序,而且好實現,所以用處也是比較多的。還有一點就是加上哨兵之後他可以提前退出。

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

【備忘】

簡單選擇排序,不穩定,n*n時間複雜度。

插入排序,選擇排序,冒泡排序的比較,他們的時間複雜度都是n*n。

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

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

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

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

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

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

桶排序:n的時間複雜度,穩定排序,非原地排序。主要思路和基數排序一樣,也是假設都在一個範圍例如機率都在0-1,而且分布還挺均勻,那麼我們也是和基數排序一樣對一個數把他劃分在他指定的地區。然後在串連這些地區就可以了。書上對每個地區使用鏈表的儲存,我認為在寸小地區的時候也會有時間在裡面。所以只是理論上的n時間複雜度。
計數排序,基數排序,桶排序的比較,我覺得他們都很有思想,不過都是在特定情況下才能發揮最大的效果。雖然效率很高,但是用的不會很廣泛。他們之間我更喜歡計數排序,來個映射的方式就直接找到了自己的位置,很高明。和基數排序和同排序只是理論上的n時間複雜度,基數排序要確定一個關鍵字的排序是n複雜度的,桶排序要確定每個地區的排序是n複雜度的。

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

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

插入排序:也使用於小資料的排序,但是我從他的思想中學到怎麼插入一個資料。

選擇排序:我學會了怎麼去獲得最大值,最小值等方法。

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

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

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

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

計數排序,基數排序,桶排序:特殊情況特殊處理。
參考:http://www.cppblog.com/shongbee2/archive/2009/04/25/81058.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.