常見算法總結 - 排序篇

本文總結了常見高頻的關於排序的算法考察。算法

1.冒泡排序

冒泡排序的思想是元素兩兩比較,將較大或者較小的元素往一端進行移動shell

public static void bubble(int[] array) {

        for (int i = 0; i < array.length - 1; i++) {

            for (int j = 0; j + 1 < array.length - i; j++) {

                if (array[j] > array[j + 1]) {

                    int tmp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = tmp;

                }

            }

        }

}

2.快速排序

快速排序的思想是隨機選取一個數字,並以這個數字爲臨界點,將數組分紅小於臨界點的的子數組和大於臨界點的子數組,並遞歸這個過程,便可實現最終的排序。後端

public static void quick(int[] array, int begin, int end) {

        if (begin >= end) {
            return;
        }

        int beginRange = begin;
        int endRange = end;

        int compareInt = array[begin];

        begin++;

        while (begin < end) {

            if (array[end] > compareInt) {
                end--;
                continue;
            }

            if (array[begin] < compareInt) {
                begin++;
                continue;
            }


            int tmp = array[begin];
            array[begin] = array[end];
            array[end] = tmp;

        }

        if (array[beginRange] > array[begin]) {

            int tmp = array[begin];
            array[begin] = array[beginRange];
            array[beginRange] = tmp;

        }

        quick(array, beginRange, begin - 1);
        quick(array, end + 1, endRange);

        return;


    }

3.選擇排序

選擇排序的思想在於每一輪選擇一個本輪的極大值,而後放入數組的尾部。最終可實現排序。數組

public static void selectSort(int[] array) {

        if (array.length == 0) {
            return;
        }

        for (int i = 0; i < array.length; i++) {

            int min = array[i];
            int minIndex = i;

            for (int j = i; j < array.length; j++) {
                if (array[j] < min) {
                    min = array[j];
                    minIndex = j;
                }
            }

            int tmp = array[i];
            array[i] = min;
            array[minIndex] = tmp;
        }
    }

4.歸併排序

歸併排序的思想在於先排序小的數組,再由小的數組合併成大數組,直到最後合併的數組大小是原數組的大小時,即完成了歸併排序。架構

public static void sort(int[] array, int left, int right) {

        //1.設置遞歸的base case
        if (left == right) {
            return;
        }
        //2.分別排兩邊
        int mid = left + (right - left) / 2;
        sort(array, left, mid);
        sort(array, mid + 1, right);
        //3.合併
        merge(array, left, mid + 1, right);

    }

public static void merge(int[] array, int leftPtr, int rightPtr, int rightBound) {

        int mid = rightPtr - 1;
        int[] temp = new int[rightBound - leftPtr + 1];

        int i = leftPtr, j = rightPtr, k = 0;
        while (i <= mid && j <= rightBound) {
            temp[k++] = array[i] <= array[j] ? array[i++] : array[j++];
        }

        while (i <= mid) {
            temp[k++] = array[i++];
        }
        while (j <= rightBound) {
            temp[k++] = array[j++];
        }

        //不要忘了把temp數組複製到arr中
        for (int m = 0; m < temp.length; m++) {
            array[leftPtr + m] = temp[m];
        }

    }

5.桶排序

桶排序的思想在於,根據數組中的最大值和最小值的差值做爲區間拆分爲N個桶,將元素落入這些桶當中,進行排序再合併。ui

public static void bucketSort(int[] array){

        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;

        for(int i = 0; i < array.length; i++){
            max = Math.max(max, array[i]);
            min = Math.min(min, array[i]);
        }

        //桶數
        int bucketNum = (max - min) / array.length + 1;
        ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
        for(int i = 0; i < bucketNum; i++){
            bucketArr.add(new ArrayList<Integer>());
        }

        //將每一個元素放入桶
        for(int i = 0; i < array.length; i++){
            int num = (array[i] - min) / (array.length);
            bucketArr.get(num).add(array[i]);
        }

        //對每一個桶進行排序
        for(int i = 0; i < bucketArr.size(); i++){
            Collections.sort(bucketArr.get(i));
        }

        int k = 0;

        for (int i = 0; i < bucketArr.size(); i++) {

            for (Integer integer : bucketArr.get(i)) {
                array[k++] = integer;
            }

        }

    }

6.計數排序

計數排序爲特殊的桶排序,一個桶的值區間爲1。url

public static int[] countSort(int[] array) {
        if (array == null || array.length == 0) {
            return null;
        }

        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;

        //找出數組中的最大最小值
        for (int i = 0; i < array.length; i++) {
            max = Math.max(max, array[i]);
            min = Math.min(min, array[i]);
        }

        int help[] = new int[max];

        //找出每一個數字出現的次數
        for (int i = 0; i < array.length; i++) {
            int mapPos = array[i] - min;
            help[mapPos]++;
        }

        int index = 0;
        for (int i = 0; i < help.length; i++) {
            while (help[i]-- > 0) {
                array[index++] = i + min;
            }
        }

        return array;
    }

7.希爾排序

希爾排序的思想在於步長。先讓元素從數組的一半做爲步長,進行比較替換,再依次減少步長,當步長爲0時,即完成排序。它主要的優點是避免冒泡排序每次交換步長爲1的低效率。.net

public static void shellSort(int[] arr) {
        //step:步長
        for (int step = arr.length / 2; step > 0; step /= 2) {
            //對一個步長區間進行比較 [step,arr.length)
            for (int i = step; i < arr.length; i++) {
                int value = arr[i];
                int j;

                //對步長區間中具體的元素進行比較
                for (j = i - step; j >= 0 && arr[j] > value; j -= step) {
                    //j爲左區間的取值,j+step爲右區間與左區間的對應值。
                    arr[j + step] = arr[j];
                }
                //此時step爲一個負數,[j + step]爲左區間上的初始交換值
                arr[j + step] = value;
            }
        }
}
筆者我的總結,若有錯誤之處望不吝指出。

本文轉自個人我的博客:《CoderV的進階筆記
歡迎加入Java後端架構技術討論羣:1398880
個人公衆號:CoderV的進階筆記,記錄技術心得
qrcodecode

相關文章
相關標籤/搜索