一、冒泡排序:
冒泡算法原理:冒泡算法就是依次比較數組中相鄰的兩個元素,如果左邊比右邊大則進行調換,以此類推,這樣第一次排序就把最大的元素放在最底下。
舉例說明:要排序數組:int[] arr = {7, 2, 6, 5, 9, 4};
第1輪排序前數組爲:[7, 2, 6, 5, 9, 4]
第1輪第1次比較:7大於2交換位置:[2, 7, 6, 5, 9, 4]
第1輪第2次比較:7大於6交換位置:[2, 6, 7, 5, 9, 4]
第1輪第3次比較:7大於5交換位置:[2, 6, 5, 7, 9, 4]
第1輪第4次比較:7小於9不交換位置:[2, 6, 5, 7, 9, 4]
第1輪第5次比較:9大於4交換位置:[2, 6, 5, 7, 4, 9]
第1輪排序後數組爲:[2, 6, 5, 7, 4, 9]
第2輪排序前數組爲:[2, 6, 5, 7, 4, 9]
第2輪第1次比較:2小於6不交換位置:[2, 6, 5, 7, 4, 9]
第2輪第2次比較:6大於5交換位置:[2, 5, 6, 7, 4, 9]
第2輪第3次比較:6小於7不交換位置:[2, 5, 6, 7, 4, 9]
第2輪第4次比較:7大於4交換位置:[2, 5, 6, 4, 7, 9]
第2輪排序後數組爲:[2, 5, 6, 4, 7, 9]
第3輪排序前數組爲:[2, 5, 6, 4, 7, 9]
第3輪第1次比較:2小於5不交換位置:[2, 5, 6, 4, 7, 9]
第3輪第2次比較:5小於6不交換位置:[2, 5, 6, 4, 7, 9]
第3輪第3次比較:6大於4交換位置:[2, 5, 4, 6, 7, 9]
第3輪排序後數組爲:[2, 5, 4, 6, 7, 9]
第4輪排序前數組爲:[2, 5, 4, 6, 7, 9]
第4輪第1次比較:2小於5不交換位置:[2, 5, 4, 6, 7, 9]
第4輪第2次比較:5大於4交換位置:[2, 4, 5, 6, 7, 9]
第4輪排序後數組爲:[2, 4, 5, 6, 7, 9]
第5輪排序前數組爲:[2, 4, 5, 6, 7, 9]
第5輪第1次比較:2小於4不交換位置:[2, 4, 5, 6, 7, 9]
第5輪排序後數組爲:[2, 4, 5, 6, 7, 9]
已排序後的數組爲:[2, 4, 5, 6, 7, 9]
由此可見:N個數字要排序完成,總共進行N-1輪排序,每i輪的排序次數爲(N-i)次,所以可以用雙重循環語句,外層控制循環多少趟,內層控制每一趟的循環次數,即
for(int i=0;i<arr.length-1;i++){
for(int j=0;j<arr.length-i-1;j++){
//交換位置
}
冒泡排序的優點:每進行一趟排序,就會少比較一次,因爲每進行一趟排序都會找出一個較大值。如上例:第一輪比較之後,排在最後的一個數一定是最大的一個數,第二輪排序的時候,只需要比較除了最後一個數以外的其他的數,同樣也能找出一個最大的數排在參與第二輪比較的數後面,第三輪比較的時候,只需要比較除了最後兩個數以外的其他的數,以此類推……也就是說,每進行一輪比較,每一輪少比較一次,一定程度上減少了算法的量。
因此冒泡排序總的時間複雜度爲O(n*n)
代碼例子:
二、快速排序
快速排序的原理:選擇一個關鍵值作爲基準值。比基準值小的都在左邊序列(一般是無序的),比基準值大的都在右邊(一般是無序的)。一般選擇序列的第一個元素。
一次循環:從後往前比較,用基準值和最後一個值比較,如果比基準值小的交換位置,如果沒有繼續比較下一個,直到找到第一個比基準值小的值才交換。找到這個值之後,又從前往後開始比較,如果有比基準值大的,交換位置,如果沒有繼續比較下一個,直到找到第一個比基準值大的值才交換。直到從前往後的比較索引>從後往前比較的索引,結束第一次循環,此時,對於基準值來說,左右兩邊就是有序的了。
接着分別比較左右兩邊的序列,重複上述的循環。
public class FastSort{
public static void main(String []args){
System.out.println("Hello World");
int[] a = {12,20,5,16,15,1,30,45,23,9};
int start = 0;
int end = a.length-1;
sort(a,start,end);
for(int i = 0; i<a.length; i++){
System.out.println(a[i]);
}
}
public void sort(int[] a,int low,int high){
int start = low;
int end = high;
int key = a[low];
while(end>start){
//從後往前比較
while(end>start&&a[end]>=key) //如果沒有比關鍵值小的,比較下一個,直到有比關鍵值小的交換位置,然後又從前往後比較
end--;
if(a[end]<=key){
int temp = a[end];
a[end] = a[start];
a[start] = temp;
}
//從前往後比較
while(end>start&&a[start]<=key)//如果沒有比關鍵值大的,比較下一個,直到有比關鍵值大的交換位置
start++;
if(a[start]>=key){
int temp = a[start];
a[start] = a[end];
a[end] = temp;
}
//此時第一次循環比較結束,關鍵值的位置已經確定了。左邊的值都比關鍵值小,右邊的值都比關鍵值大,但是兩邊的順序還有可能是不一樣的,進行下面的遞歸調用
}
//遞歸
if(start>low) sort(a,low,start-1);//左邊序列。第一個索引位置到關鍵值索引-1
if(end<high) sort(a,end+1,high);//右邊序列。從關鍵值索引+1到最後一個
}
}