插入排序(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);
    }
}

参考

1、数据结构(C语言版)严蔚敏、吴伟民 编著. 清华大学出版社 2007.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值