氣泡排序、選擇排序、插入排序,效率以及應用場景
1.氣泡排序:
氣泡排序是原理最簡單的排序,但是他是三種排序演算法中效率最低的,他的比較次數和交換資料次數時間複雜度都是O(N²)。
原理:氣泡排序是雙重迴圈,他每次排序都將最大的元素移動到最後一位,比較方式為:0 vs 1,1 vs 2,2 vs 3,。。。直到N-1 vs N,每次比較之後,下次比較不會再去比較上去比較得出的並且移動的最大資料,所以他需要逐條比較。
相應Java程式碼:
public long[] bubbleSort(long []a){
int out,in;//out外層迴圈變數,in內層迴圈變數
int count = 0;//比較次數
int num = 0;//交換次數
int length = a.length;//陣列長度
for(out=length-1;out>=1;out--){
for(in=0;in<out;in++){
if(a[in]>a[in+1]){
change(in,in+1);
num++;
}
count++;
}
}
System.out.println("比較了"+count+"次!交換了"+num+"次!");
return a;
}
2.選擇排序:
選擇排序優於氣泡排序,選擇排序的對比時間複雜度為O(N²),但是他的資料交換時間複雜度僅為O(N),在陣列排序過程中,資料的移動交換是比較耗時的,所以相對於氣泡排序而言,選擇排序的效率大大提高。
原理:選擇排序是先將陣列中最小的元素找到並且標記,即記錄最小資料的下標,將找到的最小元素移動到最左側,也就是目前的下標最小的位置,下次比較就除去上次找到並且移動的最小值,對剩下資料繼續重複上述操作,直到排序結束。所以只需要移動N-1次即可完成排序,但是對比次數還是O(N²)。
對應Java程式碼:
public long[] chooseSort(long []a){
int out,in,minIndex;//out外層迴圈,in內層迴圈,minIndex最小值下標
int countChange = 0;
int countCompare = 0;
int length = a.length;
for(out=0;out<length-1;out++){
minIndex = out;
for(in=out+1;in<length;in++){
if(a[in]<a[minIndex]){
minIndex = in;
countCompare++;
}
}
change(out, minIndex);
countChange++;
}
System.out.println("交換了"+countChange+"次!");
System.out.println("比較了"+countCompare+"次!");
return a;
}
3.插入排序:
插入排序的時間複雜度不好計算,因為他的時間複雜度是根據目前有序部分的多少決定的
原理:插入排序會將目前基本有序的一部分陣列提取出來,然後將這部分陣列的最右側的一個元素的右側元素做標記,將這個元素與前面基本有序的陣列進行比較,找到比他稍大的元素,並且移動到比他稍大的元素前面,剩餘的未排序元素重複執行上述操作,知道排序結束。所以插入排序的時間複雜度與他的基本有序部分的大小有關,如果陣列是正好逆序的,他的時間複雜度甚至不會比,氣泡排序高。
對應Java程式碼:
public long[] insertSort(long []a){
int in,out;
int length = a.length;
//out標記未排序部分的最左側元素
for(out=1;out<length;out++){
long temp = a[out];
in = out;
while(in>0&&a[in-1]>=temp){
a[in] = a[in-1];
in--;
}
a[in] = temp;
}
return a;
}
三種排序演算法的使用場景:
氣泡排序:
適用於資料量很小的排序場景,因為冒泡原理簡單
選擇排序:
適用於大多數排序場景,雖然他的對比次數較多,但是資料量大的時候,他的效率明顯優於冒泡,而且資料移動是非常耗時的,選擇排序移動次數少。
插入排序:
插入排序適用於已有部分資料有序的情況,有序部分越大越好。