1. 程式人生 > >java實現常見排序(選擇,冒泡,插入,快速,希爾,堆)

java實現常見排序(選擇,冒泡,插入,快速,希爾,堆)

選擇排序

定義一個的標誌位temp,預設為比較的第一個數的下標,分別與後面的數進行比較,若比比較的數字大,則把該數的下標賦給temp,迴圈一次結束後判斷temp的值,若temp值跟第一個數的下標不一樣,則把第一個數跟下標為temp的值交換,若temp值一樣,則說明後面的數字都比第一個數大,則不交換,繼續下一次迴圈,以此類推,直到迴圈結束,具體實現的程式碼如下:

public class Main {

    public static void main(String[] args) {
        int array[] = new int[]{2,4,6,8,1,3,5,7,10,9};
        int index,current;
        for(int i=0;i<array.length-1;i++){
            index=i;
            for(int j=i+1;j<array.length;j++){
                if(array[index]>array[j]){
                    index = j;
                }
            }
            if(index!=i){
                current = array[i];
                array[i] = array[index];
                array[index] = current;
            }
        }
    }
}

氣泡排序

氣泡排序,有一個口訣"大數沉底,小數往上飄",可見,氣泡排序每一次找出的都是當前需要排列的數字中的最大的那個值,那樣當所有的數都遍歷過後,也就從小到大排好了序,具體實現如下:

public class Main {

    public static void main(String[] args) {
        int array[] = new int[]{2,4,6,8,1,3,5,7,10,9};
        int temp;
        for(int i=0;i<array.length;i++){
            for (int j=0;j<array.length-1;j++){
                if(array[j]>array[j+1]){
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
        }
    }
}

插入排序

插入排序,可以簡單理解為在打撲克,每次拿到一張新的牌子都會對手中的牌子做比較,找到對應該牌的位置後插入,那樣在手中的牌子則一直是排好序的。具體到陣列中的話,把陣列第一位數當作手中的牌,後面的數則是要插入的數字,插入排序最壞的執行時間是O(n2)。具體程式碼實現如下:

public class Main {

    public static void main(String[] args) {
        int array[] = new int[]{2,4,6,8,1,3,5,7,10,9};
        int current,temp;
        //除去第一個數,後面均是要插入的數
        for(int i=1;i<array.length;i++){
            current = array[i]; //要插入的數
            temp = i; //記錄插入數的位置
            for(int j=i-1;j>=0;j--){
                if(array[j]>current){
                    array[j+1] = array[j];
                    temp --;
                }
            }
            array[temp] = current;
        }
    }
}

快速排序

快速排序採用了"二分"的思維。選用一個數作為基數(一般是陣列中的第一個數),從右往左找小於基數的數i,從左到右找大於基數的數j,若i!=j,則交換兩個數,若i==j,則退出當前迴圈,且array[i]與基數進行交換。這樣通過基數就形成了兩個區間,再重複以上操作,直到區間只剩下一個數字為止,最終實現小的數在基數的左邊,大的數在基數的右邊。具體實現程式碼如下:

public class Main {

    public static void main(String[] args) {
        int array[] = new int[]{2,4,6,8,1,3,5,7,10,9};
        quickSort(array,0,array.length-1);
        for (int i=0;i<array.length;i++){
            System.out.print(array[i]+" ");
        }
    }

    public static void quickSort(int[] array,int low,int high){
        if(low<high){
            int middle = sortUtil(array,low,high);
            //左邊排序
            quickSort(array,low,middle-1);
            //右邊排序
            quickSort(array,middle+1,high);
        }
    }

    public static int sortUtil(int[] array,int low,int high){
        int temp = array[low];
        while(low<high){
            //從右往左找到第一個比temp要小的值,交換
            while (low<high && array[high]>temp){
                high--;
            }
            array[low] = array[high];
            //從左往右找到第一個比temp要大的值,交換
            while (low<high && array[low]<temp){
                low++;
            }
            array[high] = array[low];
        }
        array[low] = temp;
        return low;
    }
}

希爾排序

希爾排序沿用了插入排序的原理,同時也有"二分法"的思想在裡面。先將要排序的一組數按某個增量d(n/2,n為要排序數的個數)分成若干組,每組中記錄的下標相差d.對每組中全部元素進行直接插入排序,然後再用一個較小的增量(d/2)對它進行分組,在每組中再進行直接插入排序。當增量減到1時,進行直接插入排序後,排序完成。其中,以增量d一般為待排序的序列長度的一半。

public class Main {

    public static void main(String[] args) {
        int array[] = new int[]{2,4,6,8,1,3,5,7,10,9};
        int j,temp;
        for (int length=array.length/2; length>0; length/= 2) {
            for (int i=length; i<array.length; i++) {
                temp=array[i];
                for (j=i-length;j>= 0;j-=length) {
                    if (temp<array[j]) {
                        array[j+length]=array[j];
                    } else {
                        break;
                    }
                }
                array[j + length] = temp;
            }
        }
    }
}

堆排序

堆排序的基本思想是將待排序的序列構造成一個大頂堆(從上往下,從左往右數字逐漸減小)。此時,整個序列的最大值就是堆頂的根節點。將它與堆陣列的末尾元素交換,此時末尾元素就是最大值,然後將除去末尾元素的剩餘的 n-1 個序列重新構造成一個堆,這樣就會得到 n 個元素中次大的值。如此反覆執行,便能得到一個有序序列了。 

public class Main {

    public static void main(String[] args) {
        int array[] = {2,4,6,8,1,3,5,7,10,9};
        int i,temp;
        for (i = array.length / 2 - 1; i >= 0; i--) {
            // 構建一個大頂堆
            adjust(array, i, array.length - 1);
        }
        for (i = array.length - 1; i >= 0; i--) {
            // 將堆頂記錄和當前未經排序子序列的最後一個記錄交換
            temp = array[0];
            array[0] = array[i];
            array[i] = temp;
            // 將array中前i-1個記錄重新調整為大頂堆
            adjust(array, 0, i - 1);
        }
    }

    public static void adjust(int[] array, int i, int len) {
        int temp,j;
        temp = array[i];
        for (j = 2 * i; j < len; j *= 2) {
            if (j < len && array[j] < array[j + 1]){
                ++j;
            }
            if (temp >= array[j]){
                break;
            }
            array[i] = array[j];
            i = j;
        }
        array[i] = temp;
    }
}