Java實現七大排序

  ↵

圖片來自

import com.sun.scenario.effect.Merge;

public class Sort {

    private static void swap(int arr[], int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    // 1. 冒泡排序
    // 時間複雜度爲 N^2
    // 空間複雜度O(1)
    // 穩定排序
    public static void bubbleSort(int[] arr, int len) {
        /**
         * 1>相鄰兩數進行比較,比較一遍後,最後一個數最大。
         * 2>進行n-1遍後,排列有序
         */
        for (int i = 0; i < len; i++) {
            boolean flag = true;
            for (int j = 0; j < len - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) { //相鄰兩數進行比較,若前大於後,交換倆數
                    swap(arr, j, j + 1);
                    flag = false;
                }
            }
            if (flag)
                continue;
        }
    }


    /**
     * 2. 插入排序:將數據插入前面已經排好序的隊列中
     * 平均時間複雜度爲 N^2
     * 空間複雜度O(1)
     * 穩定排序
     *
     * @param arr
     * @param length
     */
    public static void insertSort(int[] arr, int length) {
        int i, j;
        for (i = 1; i < length; i++) {
            int tmp = arr[i];
            for (j = i; j > 0 && arr[j - 1] > tmp; j--) {
                arr[j] = arr[j - 1];
            }
            arr[j] = tmp;
        }
    }


    /**
     * 3. 選擇排序:
     * 每一趟從待排序的數據元素中選擇最小(或最大)的一個元素作爲首元素,
     * 直到所有元素排完爲止。
     */
    public static void selectSort(int[] arr, int len) {
        for (int i = 0; i < len; i++) {
            int min = i;
            for (int j = i + 1; j < len; j++) {
                if (arr[j] < arr[min]) {
                    min = j;
                }
            }
            if (min != i)// 若min發生改變,進行交換
                swap(arr, i, min);
        }
    }


    /**
     * 4. 希爾排序:改進版的插入排序
     * 步長由長到短分組,進行排序,直到步長爲1爲止
     *
     * @param arr
     * @param len
     */
    public static void shellSort(int[] arr, int len) {
        for (int gap = len / 2; gap > 0; gap /= 2) {// 間隔量gap
            // 下面相當於插入排序(插入排序相當於是間隔量爲1的希爾排序)
            for (int i = gap; i < len; i++) {
                int tmp = arr[i];
                int j;
                for (j = i; j >= gap && arr[j - gap] > tmp; j -= gap) {
                    arr[j] = arr[j - gap];
                }
                arr[j] = tmp;
            }
        }
    }


    /**
     * 5.歸併排序: 拆分 合併
     * 時間複雜度: O(NlogN)
     * 空間複雜度: 對於數組來說, O(N)
     * 穩定性: 穩定排序
     *
     * @param arr
     * @param low
     * @param high 數組最後一個的下標
     */
    public static void mergeSort(int[] arr, int low, int high) {
        if (low < high) {
            // 1>拆分
            int mid = (low + high) / 2;
            // 遞歸解決左右兩邊子問題
            mergeSort(arr, low, mid);
            mergeSort(arr, mid + 1, high);
            // 2>左右歸併
            Merge(arr, low, mid, high);
        }
    }

    /**
     * <2> 合併
     *
     * @param arr  數組
     * @param low  低下標
     * @param mid  中間位置數值下標
     * @param high 高下標
     */
    public static void Merge(int[] arr, int low, int mid, int high) {
        int[] pro = new int[high - low + 1]; // 一個輔助數組
        int i = low;
        int j = mid + 1;
        int index = 0;// 輔助數組索引
        // 1>兩個數組從0開始比較,並將小的數放入輔助數組中
        while (i <= mid && j <= high) {
            if (arr[i] < arr[j])
                pro[index++] = arr[i++];
            else
                pro[index++] = arr[j++];
        }
        // 2>若;兩個數組個數不同,比較完1>後,個數少的數組會有餘留
        while (i <= mid)
            pro[index++] = arr[i++];
        while (j <= high)
            pro[index++] = arr[j++];
        // 3>將排序好的輔助數組中的值放入原數組
        for (int k = 0; k < index; k++)
            arr[k + low] = pro[k];
    }


    // 6. 堆排序:先建大堆,然後循環刪除堆頂元素
    public static void heapSort(int[] arr, int size) {
        // 創建大堆
        createHeap(arr, size);

        // 循環刪除堆頂
        for (int i = 0; i < size; i++) {
            heapPop(arr, size - i);
        }
    }

    // 堆刪
    private static void heapPop(int[] arr, int size) {
        if (size <= 1)
            return;
        swap(arr, 0, size - 1);
        adjustDown(arr, size - 1, 0);
    }

    // 創建最大堆
    private static void createHeap(int[] arr, int size) {
        if (size <= 1) // 個數爲1的話,直接返回
            return;
        int parent = (size - 1 - 1) / 2; // 從末尾起第一個非葉子結點
        for (int i = parent; i >= 0; i--) {
            adjustDown(arr, size, i);
        }
    }

    // 向下調整
    private static void adjustDown(int[] arr, int size, int i) {
        int parent = i;
        int child = 2 * parent + 1;
        while (child < size) {
            // 比較左右孩子結點大小
            if (child + 1 < size && arr[child] < arr[child + 1])
                child = child + 1;
            // 大孩子與父結點進行比較
            if (arr[parent] < arr[child])
                swap(arr, child, parent);
            // 繼續向下調整
            parent = child; // child相當於一個標記,爲與父結點進行交換的孩子的下標
            child = 2 * parent + 1;
        }
    }

    // 7. 快速排序

    /**
     * 時間複雜度: 最壞 O(N ^ 2)(如果數組是逆序的) 平均水平 O(NlogN)
     * 不穩定排序
     * @param arr
     * @param start
     * @param end
     */
    public static void quickSort(int[] arr, int start, int end) {
        int pivot = arr[start];
        int left = start;
        int right = end;

        while (left < right) {
            // 先從右邊尋找比基準值小的數
            while (left < right && arr[right] > pivot)
                right--;
            // 左邊開始尋找比基準值大的數
            while (left < right && arr[left] < pivot)
                left++;

            if (left < right)
                swap(arr, left, right);
        }
        // 此時left==right
        if (left - 1 > start) quickSort(arr, start, left - 1);
        if (right + 1 < end) quickSort(arr, right + 1, end);
    }

    public static void main(String[] args) {
        // int[] arr = {3, 1, 9, 7, 13, 0, 24, 67, 33};
        int arr[] = {6, 1, 2, 7, 4, 5, 10, 8};
        int len = arr.length;
        // insertSort(arr, len);
        // bubbleSort(arr, len);
        // mergeSort(arr, 0, len - 1);
        // shellSort(arr, len);
        // selectSort(arr, len);
        // heapSort(arr, len);
        quickSort(arr, 0, len - 1);
        for (int a : arr) {
            System.out.print(a + " ");
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章