1. 程式人生 > 實用技巧 >九大排序演算法(Java實現)

九大排序演算法(Java實現)

1、氣泡排序

public class Bubble_sort {

    /**
     * 公共氣泡排序介面
     * @param arr 帶排序陣列
     */
    public static void sort(int[] arr) {
        if (arr == null) return;
        int len = arr.length;
        for (int j = len - 1; j > 0; j--) {
            for (int i = 0; i < j; i++) {
                if (arr[i] > arr[j]) {
                    swap(arr, i, j);
                }
            }
        }
    }

    /**
     * 通用交換方法
     * @param arr  陣列
     * @param i    元素1索引
     * @param j    元素2索引
     */
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}    

2、選擇排序

public class Select_sort {

    /**
     * 選擇排序公共介面
     * @param arr
     */
    public static void sort(int[] arr) {
        if (arr == null) return;
        int len = arr.length;
        for (int j = len - 1; j > 0; j--) {
            int max = j;
            for (int i = 0; i <= j; i++) {
                if (arr[i] >= arr[max]) {
                    max = i;
                }
                swap(arr, max, j);
            }
        }
    }

    /**
     * 通用交換方法
     * @param arr  陣列
     * @param i    元素1索引
     * @param j    元素2索引
     */
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

3、插入排序

public class Insertion_sort {

    /**
     * 插入排序
     * @param arr 待排序陣列
     */
    public static void sort(int[] arr) {
        if (arr == null) return;
        // 待排序區間 [1...len-1]
        for (int j = 1; j < arr.length; j++) {
            // 比較元素
            int key = arr[j];
            int i = j - 1;
            while (i >= 0 && arr[i] > key) {
                arr[i + 1] = arr[i];
                i--;
            }
            arr[i + 1] = key;
        }
    }
}

4、快速排序

public class Quick_sort {
    private static final int MIN_VALUE = 7;

    public static void sort(int[] arr) {
        if (arr == null) return;
         sorting(arr, 0, arr.length - 1);
    }

    private static void sorting(int[] arr, int lo, int hi) {
        if (lo >= hi) return;
        if (hi- lo <= MIN_VALUE) Insertion_sort.sort(arr);
        // 切分點
        int p = partition(arr, lo, hi);
        sorting(arr, lo, p - 1);
        sorting(arr, p + 1, hi);
    }

    /**
     * 切分方法
     * @param arr 陣列
     * @param lo  左邊界
     * @param hi  右邊界
     * @return
     */
    private static int partition(int[] arr, int lo, int hi) {
        int key = arr[hi];
        // 右邊界
        int right = lo - 1;
        for (int i = lo; i < hi; i++) {
            if (arr[i] <= key) {
                right++;
                swap(arr, right, i);
            }
        }
        swap(arr, right + 1, hi);
        return right + 1;
    }

    /**
     * 通用陣列交換
     * @param arr  陣列
     * @param a    元素1索引
     * @param b    元素2索引
     */
    private static void swap(int[] arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
}

6、歸併排序

public class Merge_sort {
    /**
     * 轉為插入排序的臨界值
     */
    private static final int MIN_SIZE = 7;

    /**
     * 公共歸併排序
     * @param arr 待排序陣列
     */
    public static void sort(int[] arr) {
        if (arr == null) return;
        int[] temp = new int[arr.length];
        sorting(arr, temp, 0, arr.length - 1);
    }

    /**
     * 歸併排序(私有)
     */
    private static void sorting(int[] arr, int[] temp, int lo, int hi) {
        if (lo >= hi) return;
        // less than MIN_SIZE  user insertion_sort
        if (hi - lo <= MIN_SIZE) Insertion_sort.sort(arr);

        int mid = (lo + hi) >>> 1;
        sorting(arr, temp,  lo, mid);
        sorting(arr, temp, mid + 1, hi);
        merge(arr, temp, lo, mid, hi);
    }

    /**
     * 歸併方法
     */
    private static void merge(int[] arr, int[] temp,  int lo, int mid, int hi) {
        for (int i = lo; i <= hi; i++) {
            temp[i] = arr[i];
        }
        int i = lo;
        int j = mid + 1;
        for (int k = lo; k <= hi; k++) {
            if (i > mid) {
                arr[k] = temp[j++];
            } else if (j > hi) {
                arr[k] = temp[i++];
            } else if (temp[i] <= temp[j]) {
                arr[k] = temp[i++];
            } else {
                arr[k] = temp[j++];
            }
        }
    }
}

7、堆排序

public class Heap_sort {

    /**
     * 公共堆排序方法
     * @param arr
     */
    public static void sort(int[] arr) {
        int len = arr.length;

        // 1.堆有序
        for (int k = (len / 2) - 1; k >= 0; k--) {
            sink(arr, k, len);
        }

        // 2.交換,調整
        while (len  > 1) {
            swap(arr, 0, len - 1);
            len--;
            sink(arr, 0, len);
        }
    }

    /**
     * 下沉操作
     * 構建堆有序:任意節點大於等於其子節點的值
     */
    public static void sink(int[] arr, int k, int len) {
        while ((2 * k + 1) < len) {
            int idx = 2 * k + 1;
            if (idx < len - 1 && arr[idx] < arr[idx + 1]) {
                idx++;
            }
            // already heap sorted
            if (arr[idx] <= arr[k]) break;
            swap(arr, k, idx);
            k = idx;
        }
    }

    /**
     * 通用陣列元素交換方法
     * @param arr  陣列
     * @param i    元素 1下標
     * @param j    元素 2下標
     */
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

8、希爾排序

public class Shell_sort {
    public static void sort(int[] arr) {
        int len = arr.length;
        int h = 1;
        while (h < len / 3) {
            h = 3 * h + 1;
        }

        while (h >= 1) {
            // 內部包裹一個插入排序
            for (int j = h; j < len; j++) {
                int key = arr[j];
                int i = j - h;
                while (i >= 0 && arr[i] > key) {
                    arr[i + h] = arr[i];
                    i -= h;
                }
                arr[i + h] = key;
            }
            h = h / 3;
        }
    }
	// 陣列交換
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

9、計數排序

public class Count_sort {

    public static void sort(int[] arr, int max) {
        int[] aus = new int[max + 1];
        // 統計
        for (int num : arr) {
            aus[num] += 1;
        }
        // 重寫
        int idx = 0;
        for (int i = 0; i < aus.length; i++) {
            while (aus[i] != 0) {
                arr[idx] = i;
                idx++;
                aus[i] -= 1;
            }
        }
    }
}