美文网首页
插入排序

插入排序

作者: 阳光的技术小栈 | 来源:发表于2018-12-15 17:04 被阅读3次

分类 ------------- 内部比较排序
数据结构 ---------- 数组
最差时间复杂度 ---- 最坏情况为输入序列是降序排列的,此时时间复杂度O(n^2)
最优时间复杂度 ---- 最好情况为输入序列是升序排列的,此时时间复杂度O(n)
平均时间复杂度 ---- O(n^2)
所需辅助空间 ------ O(1)
稳定性 ------------ 稳定

原理

       对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

步骤

  1. 从第一个元素开始,该元素可以认为已经被排序
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
  5. 将新元素插入到该位置后
  6. 重复步骤2~5

代码实现

public class InsertionSort {
    void sort(Integer[] array) {
        for (int i = 1 ;i < array.length;i++){
            int j = i - 1;
            Integer item = array[i];

            while (j >= 0 && array[j] > item){
                array[j + 1] = array[j];
                j--;
            }
            array[j + 1] = item;
        }
    }

    public static void main(String[] args){
        Integer[] a = {3,4,1,9,5,2,6,10,20,16,13,11,0};
        InsertionSort sort = new InsertionSort();
        sort.sort(a);
        System.out.println("array by InsertionSort is " + Tool.arrayToString(a));
    }
}

public class Tool {
    public static <T> String arrayToString(T[] array){
        StringBuilder builder = new StringBuilder("[");
        for (int i = 0; i < array.length; i++){
            T item = array[i];
            builder.append(item + "");
            if (i != array.length - 1){
                builder.append(",");
            }
        }

        builder.append("]");
        return builder.toString();
    }

    public static <T> void exchange(T[] array, int i, int j){
        T temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

实现结果:

array by InsertionSort is [0,1,2,3,4,5,6,9,10,11,13,16,20]

插入排序的改进:二分插入排序

public class BinaryInsertionSort {
    void sort(Integer[] array) {
        for (int i = 1; i < array.length; i ++){
            Integer get = array[i];
            // left和right之间为已排序数组
            int left = 0;
            int right = i - 1;
            // 以二分发查找get的位置
            while (left <= right){
                //获取中间位置
                int middle = (left + right) / 2;
                // 不缩小left和right的距离
                if (array[middle] > get){
                    right = middle - 1;
                }
                else{
                    left = middle + 1;
                }
            }
            //所有在left右面的位置都右移了一个位置
            for (int j = i - 1; j >= left; j--)
            {
                array[j + 1] = array[j];
            }
            // 把get插入left的位置
            array[left] = get;
        }
    }

    public static void main(String[] args){
        Integer[] a = {3,4,1,9,5,2,6,10,20,16,13,11,0};
        BinaryInsertionSort sort = new BinaryInsertionSort();
        sort.sort(a);
        System.out.println("array by BinaryInsertionSort is " + Tool.arrayToString(a));
    }
}

实现结果

array by BinaryInsertionSort is [0,1,2,3,4,5,6,9,10,11,13,16,20]

相关文章

网友评论

      本文标题:插入排序

      本文链接:https://www.haomeiwen.com/subject/neyahqtx.html