插入排序(Insertion Sort) Java - 直接,折半,2路,表

/**
 * 插入排序
 *
 * @author PengHao
 * @date 2020-05-21 17:27:17
 */
public class InsertionSort {
    /**
     * 直接插入排序<br>
     * 時間複雜度:<br>
     * 1、待排序數組是遞增序列,複雜度爲O(n)<br>
     * 2、待排序數組是遞減序列,複雜度爲O(n^2)<br>
     * 空間複雜度:O(1)<br>
     * 穩定性:穩定<br>
     *
     * @param src 待排序數組
     */
    public static void straightInsertionSort(int[] src) {
        if (src == null) {
            System.err.println("待排序數組不能爲null");
            return;
        }
        for (int i = 1; i < src.length; ++i) {
            if (src[i - 1] > src[i]) {
                int key = src[i];
                int j = 0;
                // 循環將比key大的數向後挪一位
                for (j = i - 1; j >= 0 && src[j] > key; --j) {
                    src[j + 1] = src[j];
                }
                // 循環結束說明索引爲j的數不存在或者比key小,那麼key應該插入到j後面
                src[j + 1] = key;
            }
        }
    }

    /**
     * 折半插入排序<br>
     * 時間複雜度:<br>
     * 1、待排序數組是遞增序列,複雜度爲O(n)<br>
     * 2、待排序數組是遞減序列,複雜度爲O(n^2)<br>
     * 空間複雜度:O(1)<br>
     * 穩定性:穩定<br>
     *
     * @param src 待排序數組
     */
    public static void binaryInsertionSort(int[] src) {
        if (src == null) {
            System.err.println("待排序數組不能爲null");
            return;
        }
        for (int i = 1; i < src.length; ++i) {
            if (src[i - 1] > src[i]) {
                int key = src[i];
                int left = 0, right = i - 1;
                // 二分查找第一個比key大的數的索引
                while (left < right) {
                    int mid = left + (right - left >> 1);
                    if (src[mid] > key) {
                        right = mid;
                    } else {
                        left = mid + 1;
                    }
                }
                if (i - left >= 0) {
                    // 將區間[left, i - 1]整體後移一位到區間[left + 1, i]上
                    System.arraycopy(src, left, src, left + 1, i - left);
                }
                src[left] = key;
            }
        }
    }

    /**
     * 2-路插入排序
     *
     * @param src 待排序數組
     */
    public static void twoWayInsertionSort(int[] src) {
        if (src == null) {
            System.err.println("待排序數組不能爲null");
            return;
        }
        int[] arr = new int[src.length];
        arr[0] = src[0];
        int first = 0;
        int last = 0;
        for (int i = 1; i < src.length; ++i) {
            if (src[i] < arr[0]) {
                if (first == 0) {
                    first = arr.length - 1;
                    arr[first] = src[i];
                } else {
                    int j = 0;
                    for (j = first; j < arr.length && arr[j] < src[i]; ++j) {
                        arr[j - 1] = arr[j];
                    }
                    arr[j - 1] = src[i];
                    --first;
                }
            } else {
                int j = 0;
                for (j = last; j >= 0 && arr[j] > src[i]; --j) {
                    arr[j + 1] = arr[j];
                }
                arr[j + 1] = src[i];
                ++last;
            }
        }
        System.arraycopy(arr, first, src, 0, arr.length - first);
        System.arraycopy(arr, 0, src, arr.length - first, last + 1);
    }

    /**
     * 表插入排序<br>
     * 時間複雜度:<br>
     * 1、待排序數組爲遞增序列,複雜度爲O(n^2)<br>
     * 2、待排序數組爲遞減序列,複雜度爲O(n)<br>
     * 空間複雜度爲O(n)<br>
     *
     * @param src 待排序數組
     */
    public static void listInsertionSort(int[] src) {
        if (src == null) {
            System.err.println("待排序數組不能爲null");
            return;
        }
        int len = src.length;
        int[] arr = new int[len + 1];
        arr[len] = 0;
        arr[0] = len;
        for (int i = 1; i < len; ++i) {
            int j = len;
            // 找到小於src[i]的最大值的索引
            while (src[arr[j]] < src[i] && arr[arr[j]] < len) {
                j = arr[j];
            }
            // 將src[i]插入到這個數的後面
            arr[i] = arr[j];
            arr[j] = i;
        }
        int[] res = new int[len];
        for (int i = arr[len], j = 0; i < len; i = arr[i], ++j) {
            res[j] = src[i];
        }
        System.arraycopy(res, 0, src, 0, len);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章