插入排序-递归+二分查找


title: 插入排序
date: 2019-07-21 09:58:02
summary: 插入排序-迭代+二分查找(Insertion-Sort)
categories: 数据结构和算法
tags: [LeetCode,算法导论]

题目:

leetcode(912):
	给定一个整数数组 nums,将该数组升序排列。
		示例 1:   
			输入:[5,2,3,1]
			输出:[1,2,3,5]
		示例 2:
			输入:[5,1,1,2,0,0]
			输出:[0,0,1,1,2,5]
	提示:
		1 <= A.length <= 10000
		-50000 <= A[i] <= 50000
	来源:力扣(LeetCode)
	链接:https://leetcode-cn.com/problems/sort-an-array
	著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

	(稍后总结)

具体代码:

class Solution {
	public int[] sortArray(int[] nums) {
        if(nums == null || nums.length == 1){
            return nums;
        }

        for(int currentInsetIndex = 1; currentInsetIndex < nums.length; currentInsetIndex++){
            // currentInset:当前进行插入的数字
            int currentInset = nums[currentInsetIndex];
            
            // 当前进行比较的下标
            int currentCompareIndex = currentInsetIndex - 1;

            // 二分查找到正确位置
            int index = Solution.binarySearch(nums, 0, currentCompareIndex, currentInset);

            // 在正确位置进行插入
            Solution.insertNum(nums, 0, currentInsetIndex, index);
        }

        return nums;
    }

    /**
     * 二分查找数值在已排序数组中正确的下标
     * @param array 进行查找的数组
     * @param lower 查找下界
     * @param up 查找上界
     * @param num 查找数字
     * @return 下标
     */
    public static int binarySearch(int[] array, int lower, int up, int num){

        int lowerSearch = lower;
        int upSearch = up;

        int middle = (upSearch - lowerSearch)/2 + lowerSearch;
        while(lowerSearch <= upSearch){

            if(array[middle] > num){
                upSearch = middle - 1;
            }else{
                lowerSearch = middle + 1;
            }
            middle = (upSearch - lowerSearch)/2 + lowerSearch;
        }

        return middle;
    }

    /**
     * 插入值到数组中(数组范围内的一个数插入到本数组的另一个位置)
     * @param array 进行插入的数组
     * @param lower 插入范围下界
     * @param up 插入范围上界(也是要进行插入的值)
     * @param index 插入下标
     */
    public static void  insertNum(int[] array, int lower, int up, int index){
        // unlawfulness
        if(up <= index && index < lower){
            return;
        }

        // save a value of insert
        int num = array[up];

        // move inserted value of last to last
        for (int i = up; i > index && i > lower; i--){
            array[i] = array[i-1];
        }

        // insert value
        array[index] = num;
    }
}

运行结果:

执行结果:
	通过 显示详情
	执行用时 :
		314 ms, 在所有 Java 提交中击败了8.58%的用户
	内存消耗 :
		52.1 MB, 在所有 Java 提交中击败了100.00%的用户

结果分析:

	本来对这个算法寄予了很大期望:
		1.利用二分查找法解决了进行线性查找而需要的线性时间,进而把查找时间压缩到了lg(n).
		2.利用迭代替换掉递归,进而解决了在数组长度过大时出现的java.lang.StackOverflowError
	对于第一次用算法结合的方式进行排序冷静分析后:
		1.对于内存消耗还是很好理解,原址排序.
		2.对于执行用时,虽然用二分查找法代替掉了线性查找,但还是改变不了算法本身是插入排序,而对于插入排序最忌惮的就是数组长度.

你可能感兴趣的:(LeetCode,算法,数据结构)