1. 程式人生 > >JAVA常用演算法之冒泡、選擇、快速

JAVA常用演算法之冒泡、選擇、快速

排序:對一組資料進行從小到大(或從大到小)的順序排列。
排序演算法有很多種,這裡介紹Java中面試經常出現的三種排序方式:冒泡、選擇、快速。

冒泡
顧明思義,是氣泡從液體的底部到頂部的過程,就像串糖葫蘆一樣,先決定最下面的資料。在演算法的過程中是把一組資料從第一位開始兩兩比較(第1位和第2位,第2位和第3位…),選擇大的值或者比較小的值交換到後面的位置。以這種方式比較第一輪後,這組資料中最大的值或者最小的就沉澱到最下面,以此類推倒數第二、三位等。

選擇
選擇排序的方式,其實更加貼近我們正常的思考方式,就是從一組的資料的開始位置,拿出這個資料,然後依次和其他位置中資料比較,比如找最大值,只要發現後面有比其大的值就進行互換,這樣第一輪下來,第一個位置上的資料就是最大值,然後從第二位依次類推。

快速:參考百度百科:快速排序演算法
通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。

程式碼實現如下:

方法:

public class ArraySort{  
    //冒泡  
    public static void bubbleSort(int[] arr) {  
        /*兩個for迴圈巢狀, 
         *外面的for迴圈決定一個長度為m的資料要比較多少輪才能完成排序。 
         *利用舉例歸類的方式,比如長度為5、8、9,需要4(第一輪:1和2,2和3,3和4,4和5; 
         *第二輪:1和2,2和3,3和4,5號位置已經上一次中排列好,不需要在參與比較;第三輪:1和2 
         *,2和3;第四輪:1和2),7,8輪; 
         *裡面的for迴圈決定每次一輪迴圈中要做多少次才能結束,這裡面的規律就在長度為5的舉例中, 
         *可以歸類,就是4、3、2、1,,也就是它跟輪數有關係,輪數增加,比較次數就減少,比較次數 
         * n = m - i,i輪數 
         */
for(int i = 0; i < arr.length - 1; i++) { for(int j = 0; j < arr.length - 1 - i; j++){ //從小到大,大的值放後面位置。 if (arr[j] > arr[j+1]){ swap(arr,j,j+1); } } } } //選擇
public static void selectSort(int[] arr) { /* * 同理兩個for迴圈,外面的for是幾輪,因為最後一個不需要比較,所以是長度的m-1輪 * 裡面的for是指每一輪比較的過程,一個就是起始位隨著輪數後移,另外比較的次數也隨著減少 * 規律同冒泡 */ for(int i = 0; i < arr.length - 1; i++){ for(int j = i + 1; j < arr.length; j++){ if(arr[i] > arr[j]) { swap(arr,i,j); } } } } private static void swap(int[] arr,int index1,int index2){ int temp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = temp; } //快速排序 public static void quickSort(int[] arr,int low,int high){ int l = low; int h = high; //基數 int povit = arr[low]; //一趟快速排序,即l = h,這時povit的位置就固定了,左邊都是小於它的值,右邊都是大於它的值。 while(l < h){ //從右邊開始,通過高位角標h的自減,從最右位向低位逐一取出陣列中的值。l < h排除了l=h情況 while(povit < arr[h] && l < h){ h--; } //如果上面的迴圈結束,且l != h,說明右邊出現小於povit元素,需要互換位置 if(l < h){ swap(arr,l,h); l++;//從後一位開始讀取陣列 } //從左邊開始,通過低位角標l的自增,從最左邊向高位逐一取出數值中的值。 while(povit > arr[l] && l < h){ l++; } //如果上面的迴圈結束,且l != h,說明左邊出現大於povit元素,需要互換位置 if(l < h){ swap(arr,l,h); h++; } //向下繼續最外面的while迴圈,直到l = h } //遞迴,povit左邊繼續呼叫quickSort if(l > low) quickSort(arr,low,l-1); //遞迴,povit右邊繼續呼叫quickSort if(h < high) quickSort(arr,l+1,high); }

測試:

public class SortTest {  
    public static void main(String[] agrs){  
        //定義一個一維組數  
        int[] arr1 = {5,8,3,9,10,55,32};  
        ArraySort.bubbleSort(arr1);  
        printArray(arr1);  
        int[] arr2 = {5,8,3,9,10,55,32};  
        ArraySort.selectSort(arr2);  
        printArray(arr2);  
        int[] arr3 = {5,8,3,9,10,55,32};  
        ArraySort.quickSort(arr3,0,arr3.length-1);  
        printArray(arr3);  
    }  

    public static void printArray(int[] arr){  
        String str = "[";  
        for(int i = 0; i < arr.length; i++) {  
            str = str + arr[i] + ",";  
        }  
        str = str.substring(0,str.length() - 1);  
        str = str + "]";  
        System.out.print(str);  
        System.out.println("");  
    }  
}