http://www.cnblogs.com/biyeymyhjob/archive/2012/07/17/2591457.htmlphp
http://www.cnblogs.com/codingmylife/archive/2012/10/21/2732980.htmlhtml
冒泡排序:最好狀況需比較n-1次,最壞狀況需比較n(n-1)/2;
選擇排序:最好狀況需比較n(n-1)/2,最壞狀況需比較n(n-1)/2;
對分排序:最好狀況需比較n/2logn,最壞狀況需比較近似nlogn;
冒泡排序java
名稱 | 數據對象 | 穩定性 | 時間複雜度 | 空間複雜度 | 描述 | ||
---|---|---|---|---|---|---|---|
平均 | 最壞 | ||||||
插入排序 | 數組、鏈表 | √ | ![]() |
O(1) | (有序區,無序區)。把無序區的第一個元素插入到有序區的合適的位置。對數組:比較得少,換得多。 | ||
直接選擇排序 | 數組 | × | ![]() |
O(1) | (有序區,無序區)。在無序區裏找一個最小的元素跟在有序區的後面。 對數組:比較得多,換得少。 | ||
鏈表 | √ | ||||||
堆排序 | 數組 | × | O(nlogn) | O(1) | (最大堆,有序區)。從堆頂把根卸出來放在有序區以前,再恢復堆。 | ||
歸併排序 | 數組、鏈表 | √ | O(nlogn) | O(n) +O(logn) , 若是不是從下到上 | 把數據分爲兩段,從兩段中逐個選最小的元素移入新數據段的末尾。可從上到下或從下到上進行。 | ||
快速排序 | 數組 | × | O(nlogn) | ![]() |
O(logn) ,O(n) | (小數,樞紐元,大數)。 | |
Accum qsort | 鏈表 | √ | O(nlogn) | ![]() |
O(logn) ,O(n) | (無序區,有序區)。把無序區分爲(小數,樞紐元,大數),從後到前壓入有序區。 | |
決策樹排序 | √ | O(logn!) | O(n!) | O(n) <O(logn!) <O(nlogn) | |||
計數排序 | 數組、鏈表 | √ | O(n) | O(n+m) | 統計小於等於該元素值的元素的個數 i,因而該元素就放在目標數組的索引 i位。(i≥0) | ||
桶排序 | 數組、鏈表 | √ | O(n) | O(m) | 將值爲 i 的元素放入i 號桶,最後依次把桶裏的元素倒出來。 | ||
基數排序 | 數組、鏈表 | √ | 一種多關鍵字的排序算法,可用桶排序實現。 |
冒泡排序的主要思想就是經過一趟排序,將數組中的最大值轉移到的數組最後一個元素。一個有n個元素的數組,那麼通過(n-1)趟排序之後,就可以完成排序。由於若是(n-1)個元素的位置肯定了,那麼最後的那一個元素的位置也就肯定了。還有須要注意的是每一趟排序都能肯定數組中的一個元素位置,所以通過一趟排序之後,須要進行排序比較的元素就減小一個。c++
在每一趟排序過程當中,都是從數組元素第一個開始,依次比較相鄰的兩個數,將小數放在前面,大數放在後面。即在第一趟:首先比較第1個和第2個數,將小數放前,大數放後。而後比較第2個數和第3個數,將小數放前,大數放後,如此繼續,直至比較最後兩個數,將小數放前,大數放後。至此第一趟結束,將最大的數放到了最後。在第二趟:仍從第一對數開始比較(由於可能因爲第2個數和第3個數的交換,使得第1個數再也不小於第2個數),將小數放前,大數放後,一直比較到倒數第二個數(倒數第一的位置上已是最大的),第二趟結束,在倒數第二的位置上獲得一個新的最大數(其實在整個數列中是第二大的數)。如此下去,重複以上過程,直至最終完成排序。因爲在排序過程當中老是小數往前放,大數日後放,至關於氣泡往上升,因此稱做冒泡排序。算法
冒泡排序法存在的不足及改進方法:windows
第一,在排序過程當中,執行完當前的第k趟排序後,可能數據已所有排序完備,可是程序沒法判斷是否完成排序,會繼續執行剩下的(n-1-k)趟排序。爲了解決這一不足,能夠設置一個標誌位flag,將其初始值設置爲非0,表示被排序的數組是一個無序的數組。每一次排序開始前設置flag值爲0,表示假設已經完成排序,若是這一趟排序過程當中都沒有數據發生交換,則flag的值就爲0;可是當這一趟排序過程當中存在數據交換時,修改flag爲非0,表示這一趟仍然有數據沒有完成排序。在新一輪排序開始時,檢查此標誌,若此標誌爲0,表示上一次沒有作過交換數據,則表示通過上一趟的排序,已經完成了對數組的排序,排序結束;不然繼續進行排序;數組
根據上述思路進行改進的冒泡排序代碼實現以下:ide
第二,當排序的數據比較多時排序的時間會明顯延長。改進方法:快速排序:具體作法:任意選取某一記錄(一般取第一個記錄),比較其關鍵字與全部記錄的關鍵字,並將關鍵字比它小的記錄所有放在它的前面,將比它大的記錄均存放在它的後面,這樣,通過一次排序以後,可將全部記錄以該記錄所在的分界點分爲兩部分,而後分別對這兩部分進行快速排序,直至排序完。也就是說,利用快速排序過程當中的Partition()方法返回的index將須要排序的元素分爲兩段,在index前面的數據都比index位置的數據小,在index後面的元素都比index位置的數據大。而後對先後兩段數據進行冒泡排序,這樣縮小的冒泡排序的數據量。函數
局部冒泡排序算法對冒泡排序的改進:性能
在冒泡排序中,一趟掃描有可能無數據交換,也有可能有一次或屢次數據交換,在傳統的冒泡排序算法及近年來的一些改進的算法中,只記錄一趟掃描有無數據交換的信息,對數據交換髮生的位置信息則不予處理。爲了充分利用這一信息,能夠在一趟全局掃描中,對每一反序數據對進行局部冒泡排序處理,稱之爲局部冒泡排序。局部冒泡排序與冒泡排序算法具備相同的時間複雜度,而且在正序和逆序的狀況下,所需的關鍵字的比較次數和移動次數徹底相同。因爲局部冒泡排序和冒泡排序的數據移動次數老是相同的,而局部冒泡排序所需關鍵字的比較次數常少於冒泡排序,這意味着局部冒泡排序極可能在平均比較次數上對冒泡排序有所改進,當比較次數較少的優勢不足以抵消其程序複雜度所帶來的額外開銷,而當數據量較大時,局部冒泡排序的時間性能則明顯優於冒泡排序。
參考前面寫的博文:
c++實現
java實現(ps:2012-10-8)
此處使用異或方法交換兩個元素的值存在一些bug,建議仍是使用常規的交換元素方法。
參考文獻:白話經典算法系列之五 歸併排序的實現
在這裏咱們看到咱們merge的分段是arry[start...mid]跟arry[mid+1...end],咱們不能分紅arry[start...mid-1]跟arry[mid...end],這是由於mid=(start+end)/2,假如start=1,end=2,則mid=1,此時調用MergeSort(arry,start=1,end=3,temp);會就變成了MergeSort(arry,mid=1,end=3,temp)的死循環了。