1)分類: java
1)插入排序(直接插入排序、希爾排序) 算法
2)交換排序(冒泡排序、快速排序) 數組
3)選擇排序(直接選擇排序、堆排序) ui
4)歸併排序 spa
5)分配排序(箱排序、基數排序) code
所需輔助空間最多:歸併排序 排序
所需輔助空間最少:堆排序 遞歸
平均速度最快:快速排序 it
不穩定:快速排序,希爾排序,堆排序。 io
1)選擇排序算法的時候
1.數據的規模 ; 2.數據的類型 ; 3.數據已有的順序
通常來講,當數據規模較小時,應選擇直接插入排序或冒泡排序。任何排序算法在數據量小時基本體現不出來差距。考慮數據的類型,好比若是所有是正整數,那麼考慮使用桶排序爲最優。 考慮數據已有順序,快排是一種不穩定的排序(固然能夠改進),對於大部分排好的數據,快排會浪費大量沒必要要的步驟。數據量極小,而起已經基本排好序,冒泡是最佳選擇。咱們說快排好,是指大量隨機數據下,快排效果最理想。而不是全部狀況。
快速排序:
快 速排序是對冒泡排序的一種改進。它的基本思想是:經過一躺排序將要排序的數據分割成獨立的兩部分,其中一部分的全部數據都比另一不部分的全部數據都要 小,而後再按次方法對這兩部分數據分別進行快速排序,整個排序過程能夠遞歸進行,以此達到整個數據變成有序序列。最壞狀況的時間複雜度爲O(n2),最好 狀況時間複雜度爲O(nlog2n)。
假設要排序的數組是A[1]……A[N],首先任意選取一個數據(一般選用第一個數據)做爲關鍵數據,而後將全部比它的數都放到它前面,全部比它大的數都放到它後面,這個過程稱爲一躺快速排序。一趟快速排序的算法是:
1)、設置兩個變量I、J,排序開始的時候I:=1,J:=N;
2)以第一個數組元素做爲關鍵數據,賦值給X,即X:=A[1];
3)、從J開始向前搜索,即由後開始向前搜索(J:=J-1),找到第一個小於X的值,二者交換;
4)、從I開始向後搜索,即由前開始向後搜索(I:=I+1),找到第一個大於X的值,二者交換;
5)、重複第三、4步,直到I=J;
例如:待排序的數組A的值分別是:(初始關鍵數據X:=49)
A[1] A[2] A[3] A[4] A[5] A[6] A[7]:
49 38 65 97 76 13 27
進行第一次交換後: 27 38 65 97 76 13 49
( 按照算法的第三步從後面開始找)
進行第二次交換後: 27 38 49 97 76 13 65
( 按照算法的第四步從前面開始找>X的值,65>49,二者交換,此時I:=3 )
進行第三次交換後: 27 38 13 97 76 49 65
( 按照算法的第五步將又一次執行算法的第三步從後開始找)
進行第四次交換後: 27 38 13 49 76 97 65
( 按照算法的第四步從前面開始找大於X的值,97>49,二者交換,此時J:=4 )
此時再執行第三步的時候就發現I=J,從而結束一躺快速排序,那麼通過一躺快速排序以後的結果是:27 38 13 49 76 97 65,即因此大於49的數所有在49的後面,因此小於49的數所有在49的前面。
快速排序就是遞歸調用此過程——在以49爲中點分割這個數據序列,分別對前面一部分和後面一部分進行相似的快速排序,從而完成所有數據序列的快速排序,最後把此數據序列變成一個有序的序列,根據這種思想對於上述數組A的快速排序的全過程如圖6所示:
初始狀態 {49 38 65 97 76 13 27}
進行一次快速排序以後劃分爲 {27 38 13} 49 {76 97 65}
分別對先後兩部分進行快速排序 {13} 27 {38}
結束 結束 {49 65} 76 {97}
49 {65} 結束
結束
圖6 快速排序全過程
/** * 快速排序實現算法 * @author Administrator */ public class SortTest { /** * @param args */ public static void main(String[] args) { // TODO 自動生成方法存根 quicksort qs = new quicksort(); int data[] = {44,22,2,32,54,22,88,77,99,11}; qs.data = data; qs.sort(0, qs.data.length-1); qs.display(); } } class quicksort { public int data[]; /*分割、分開*/ private int partition(int sortArray[],int low,int hight) { int key = sortArray[low]; while(low<hight) { while(low<hight && sortArray[hight]>=key) hight--; sortArray[low] = sortArray[hight]; while(low<hight && sortArray[low]<=key) low++; sortArray[hight] = sortArray[low]; } sortArray[low] = key; return low; } public void sort(int low,int hight) { if(low<hight) { int result = partition(data,low,hight); sort(low,result-1); sort(result+1,hight); } } public void display() { for(int i=0;i<data.length;i++) { System.out.print(data[i]); System.out.print(" "); } } }
堆排序:首先,數組裏面用層次遍歷的順序放一棵徹底二叉樹。從最後一個非終端結點往前面調整,直到到達根結點,這個時候除根節點之外的全部非終端節點都已經知足堆得條件了,因而須要調整根節點使得整個樹知足堆得條件,因而從根節點開始,沿着它的兒子們往下面走(最大堆沿着最大的兒子走,最小堆沿着最小的兒子走)。主程序裏面,首先從最後一個非終端節點開始調整到根也調整完,造成一個heap, 而後將heap的根放到後面去(即:每次的樹大小會變化,可是 root都是在1的位置,以方便計算兒子們的index,因此若是須要升序排列,則要逐步大頂堆。由於根節點被一個個放在後面去了。降序排列則要創建小頂堆)