八大排序算法之3插入排序算法和其优化

插入排序算法思路

给定一个无续的数组,对其进行排序,思路如下
相当于用两个数组进行排序,一个是无序的,一个是有序的,每次从无序数组中拿出一个数,与有序的数组中的数进行比较,确定插入的位置后插在有序数组中,最后输出有序数组即可:

  1. 首先从无序数组中取出第一个数直接放在有序数组中,放到第一个位置。
  2. 然后从无序数组中拿出第二个数,先与有序数组中的数进行比较,如果此数较大,则放在有序数组中那个数的后面,如果此数小,则放在前面
  3. 从无序数组中取出取出第三个数,与有序数组中的数进行比较,确定存放的位置后,进行插入。
  4. 以此类推。。。

插入算法粗暴实现

package com.njupt.Algorithm.insert;

import java.util.Arrays;

/**
 * Creat with IntelliJ IDEA
 *
 * @Auther:倔强的加瓦
 * @Date:2021/07/18/18:12
 * @Description:
 */
public class Insert {
    public static void main(String[] args) {
        int[] arr = {101, 34, 119, 1};
        insertMethod(arr);
    }

    //插入排序
    public static void insertMethod(int[] arr) {
        //第一轮,先从无序数组中取出第2个数与有序数组中的比较
        int insertVal = arr[1];
        int insertIndex = 1 - 1;
        //当取出的数小于有序数组中的那个数则进行交换
        while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
            //如果无序数组中那个数更小,则需要将有序数组中的数往后移动一位,空出来给要插入的那个数
            arr[insertIndex + 1] = arr[insertIndex];
            //一直向前比较,调整插入的位置
            insertIndex--;
}
//确定好插入的位置后,开始插入数据
        arr[insertIndex + 1] = insertVal;

        System.out.println("第一轮输出");
        System.out.println(Arrays.toString(arr));

        //第2轮,应该拿出无序数组中的第三个数到有序数组中比较
        insertVal = arr[2];
        //假设要插入的数插入的位置
        insertIndex = 2 - 1;
        //如果有序数组中要插入元素的位置的数大于拿出来的那个数,则将要插入位置的数后移一位
        while (insertIndex >= 0 && insertVal < arr[insertIndex]) {

            arr[insertIndex + 1] = arr[insertIndex];
            //调整要插入的位置
            insertIndex--;
        }
        //找到要插入位置后,将要插入的数插入即可
        arr[insertIndex + 1] = insertVal;
        System.out.println("第2轮输出");
        System.out.println(Arrays.toString(arr));

        //第3轮
        //从无序数组中取出第四个数,拿出来与有序数组中的数进行比较
        insertVal = arr[3];
        //假设要插入有序数组中的位置
        insertIndex = 3 - 1;
        //如果新数组中要插入位置的数大于拿出来的数,则需要将新数组的数后移,给插入的数腾位置
        while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
            arr[insertIndex + 1] = arr[insertIndex];
            insertIndex--;
        }
        arr[insertIndex + 1] = insertVal;
        System.out.println("第3轮输出");
        System.out.println(Arrays.toString(arr));
    }
}

测试结果:

第一轮输出
[34, 101, 119, 1]2轮输出
[34, 101, 119, 1]3轮输出
[1, 34, 101, 119]

Process finished with exit code 0

真正的插入算法

package com.njupt.Algorithm.insert;

import java.util.Arrays;

/**
 * Creat with IntelliJ IDEA
 *
 * @Auther:倔强的加瓦
 * @Date:2021/07/18/19:25
 * @Description:
 */
public class RealInsert {
    public static void main(String[] args) {
        int[] arr = {101, 34, 119, 1};
        insertMethod(arr);
    }

    public static void insertMethod(int[] arr) {
        //需要比较n-1次
        for (int i = 1; i < arr.length; i++) {
            int insertVal = arr[i];
            int insertIndex = i - 1;
            while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
                arr[insertIndex + 1] = arr[insertIndex];
                insertIndex--;
            }
            //需要优化的地方
            arr[insertIndex + 1] = insertVal;
            
            System.out.println("第" + (i) + "轮输入");
            System.out.println(Arrays.toString(arr));
        }

    }

}

1轮输出
[34, 101, 119, 1]2轮输出
[34, 101, 119, 1]3轮输出
[1, 34, 101, 119]

存在的问题:当判断出要插入新数组的位置时,如果恰好就是假设的插入位置时,不需要在进行插数操作,直接进行下一次取数判断即可。

插入排序算法的优化

package com.njupt.Algorithm.insert;

import java.util.Arrays;

/**
 * Creat with IntelliJ IDEA
 *
 * @Auther:倔强的加瓦
 * @Date:2021/07/18/19:39
 * @Description:
 */
public class BetterInsert {
    public static void main(String[] args) {
        int[] arr = {101, 34, 119, 1};
        insertMethod(arr);
    }

    public static void insertMethod(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            int insertVal = arr[i];
            int insertIndex = i - 1;
            while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
                arr[insertIndex + 1] = arr[insertIndex];
                insertIndex--;
            }

            if (insertIndex + 1 != i) {
                arr[insertIndex + 1] = insertVal;
                System.out.println("第" + i + "轮输出");
                System.out.println(Arrays.toString(arr));
            } else {
                System.out.println("第" + i + "轮不需要位置,直接放到假设的位置即可");
                System.out.println(Arrays.toString(arr));

            }


        }

    }
}

测试代码:

1轮输出
[34, 101, 119, 1]2轮不需要找位置,直接放到假设的位置即可
[34, 101, 119, 1]3轮输出
[1, 34, 101, 119]

Process finished with exit code 0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值