[图解] 插入排序

2018-09-13  本文已影响0人  CoderJed

1. 图示过程

插入排序图示

2. 动图展示

3. 文字叙述过程

4. Java代码实现

public static void insertionSort(int[] nums) {

    if (nums == null || nums.length < 2) {
        return;
    }

    for(int i = 1; i < nums.length; i++) {
        for(int j = i - 1; j >= 0 && nums[j] > nums[j + 1]; j--) {
            ArrayUtils.swap(nums, j, j + 1);
        }
    }

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

5. 复杂度

6. 优化

上面的算法的缺点:在第i-1趟插入时,需要把第i个元素插入到前面的i-1个元素中,该算法总是从i-1个元素开始逐个比较之前的每个元素,直到找到第i个元素的插入位置,这显然没有利用前面0~i-1个元素已经有序的特点

优化:在0~i-1个有序元素给第i个元素寻找插入的位置时,使用二分查找法可以有效提高查找插入位置的时间效率,经过优化的插入排序称为折半插入排序,折半插入排序的时间复杂度为O(n*logn)

/**
 * 折半插入排序
 */
public static void binaryInsertionSort(int[] nums) {

    if (nums == null || nums.length < 2) {
        return;
    }

    for(int i = 1; i < nums.length; i++) {
        int temp = nums[i];
        // 通过二分查找找到插入的位置
        int insertIndex = findInsertIndex(nums, 0, i - 1, nums[i]);
        // 插入位置之后的元素依次向后移动
        for(int j = i; j > insertIndex; j--) {
            nums[j] = nums[j - 1];
        }
        // 更新插入位置的值
        nums[insertIndex] = temp;
    }

}

/**
 * 在有序数组 nums 的[L, R]部分上,找到 value 的插入位置
 */
public static int findInsertIndex(int[] nums, int L, int R, int value) {

    while(L <= R) {
        int mid = L + ((R - L) / 2);
        if(value > nums[mid]) {
            L = mid + 1;
        } else {
            R = mid - 1;
        }
    }

    return L;

}
上一篇下一篇

猜你喜欢

热点阅读