简单算法之插入排序(二)

一、思路

假设有8个数字未被排序。
默认第一位数为已排序数字a,从剩余的7个未排序数字中拿出第一个数b,b与a进行比较,如果b小于a,则将b插入到a位置前边。

二、案例分析

待排序数据:8 6 2 3 1 5 7 4
第一轮排序:
    默认数字8已排序,剩余7个未排序数字中,数字6为未排序集合中的第一个数字,6与8进行比较大小。6小于8,因此6插入到8前边,得到如下结果:
    6 8 2 3 1 5 7 4
    前2个数字已经排序,剩余6个数字未排序。
    
第二轮排序:
    剩余6个未排序数字中,数字2为未排序集合中的第一个数字,2与8进行比较大小,2小于8,因此2插入到8前边,得到如下结果:
    6 2 8 3 1 5 7 4
    2前边还有一个已排序的数字,2与6进行比较大小,2小于6,因此2插入到6的前边,得到如下结果:
    2 6 8 3 1 5 7 4
    前3个数字已经排序,剩余5个数字未排序。
......

542859-20170820102133521-912330668.gif

三、编码

public class InsertionSort {

    // 我们的算法类不允许产生任何实例
    private InsertionSort() {
    }

    public static void sort(int[] arr) {

        int n = arr.length;
        for (int i = 1; i < n; i++) {

            // 寻找元素arr[i]合适的插入位置

            // 写法1
//          for (int j = i; j > 0; j--) {
//              if (arr[j] < arr[j - 1]) {
//                  swap(arr, j, j - 1);
//              } else {
//                  break;
//              }
//
//          }

            // 写法2
             for (int j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
                 swap(arr, j, j - 1);
             }

        }
    }

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

    // 测试InsertionSort
    public static void main(String[] args) {

        int[] arr = { 8, 6, 2, 3, 1, 5, 7, 4 };
        InsertionSort.sort(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]);
            System.out.print(' ');
        }
        System.out.println();
    }
}

四、优化思路

上述算法思路中,第N轮排序,至多要进行N次数据的位置交换(swap方法中3个赋值操作),这个过程非常耗时,因此需要优化。
优化思路:
    假设有8个数字未被排序。
    默认第一位数为已排序数字a,从剩余的7个未排序数字中将第一个数b复制一份数据b。副本b与前一个数进行比较大小,如果b小于a,则a移入到b的位置,b插入到a的位置。

五、优化案例分析

待排序数据:8 6 2 3 1 5 7 4
第一轮排序:
     默认数字8已排序,剩余7个未排序集合中,数字6为未排序集合中的第一个数字,将其复制一份数据。6与8比较大小,6小于8,8移入到6的位置,6插入到8的位置。得到如下结果:
     6 8 2 3 1 5 7 4
第二轮排序:
    假设前2数字已排序,剩余6个未排序的集合中,数字2为未排序集合的第一个数字,将其复制一个数据。2与8比较大小,2小于8,8移入到2的位置,2再与6比较大小,2小于6,6移入到8之前的位置,2插入到6的位置。得到如下结果:
    2 6 8 3 1 5 7 4
......

542859-20170820175707365-446469791.gif

六、优化编码

public static void sortAdvance(int[] arr) {
    int n = arr.length;
    for (int i = 1; i < n; i++) {
        // 拷贝数据
        int e = arr[i];
        // j保存元素e应该插入的位置
        int j;
        for (j = i; j > 0 && arr[j - 1] > e; j--) {
            arr[j] = arr[j - 1];
        }
        arr[j] = e;
    }
}

转载于:https://www.cnblogs.com/moonlightL/p/7400822.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值