插入排序算法

文章详细介绍了插入排序的工作原理,通过构建有序表和无序表的概念,描述了如何通过比较和元素移动找到插入位置的过程。代码实现展示了插入排序的Java代码,强调了有序表和无序表是抽象概念。文章还提到了插入排序的时间复杂度为O(n^2),并通过性能测试显示其在特定情况下可能优于选择排序。
摘要由CSDN通过智能技术生成

该算法主要就是:找位置,如果不满足规则就让前一个元素往后移动,直到找到位置然后放进去;

因此该算法减少了数组中很多不必要的元素位置交换的操作

插入式排序属于内部排序法,是对于欲排序的元素以插入的方式找寻该元素的适当位置,以达到排序的目的

它的基本思想是:把n个待排序的元素看成(想象出来的)一个有序表和一个无序表,开始时有序表只包含一个元素无序表中包含n-1个元素,排序的过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表的排序码进行比较,将它插入到有序表中的适当位置,使之称为新的有序表;

较难理解,脑子里面要时刻抽象出这个有序表和无序表;

图解

流程分析

1.把整个数组看成一个有序表和无序表,其中最开始有序表就只有arr[0]一个元素;

2.无序表有arr[1]-arr[n]元素;

3.每次从无序表的第一个位置取出元素,按照规则插入到有序表中;

注意:这个有序表和无序表是我们想象出来的,并不真实存在

代码实现

/**
 * @Author:Strine
 * 插入排序的实现
 * */

public static void getInsertSort(int arr[]){
    long startTime = System.currentTimeMillis();
    for (int i = 1; i < arr.length; i++) {
        int insertIndex=i-1;// 有序表的第insertIndex个元素;
        int insertVal = arr[i]; //相当于无序表中的第一个元素
        while (insertIndex>=0&&insertVal<arr[insertIndex]){
            //无需表的这个元素比有序表的最后一个元素那就让有序表的这个元素后移
            arr[insertIndex+1]=arr[insertIndex];
            //从后往前遍历有序表
            insertIndex--;
        }
       //当循环完之后,说明找到了该元素的位置,也就是前一个位置的元素比当前元素还小了;
            //如果说当前这个元素比之前的元素都要大,也就是说他就应该在这个位置,那么就不变
            if (insertIndex+1!=i){
                arr[insertIndex+1]=insertVal;
            }
    }
    long endTime = System.currentTimeMillis();

    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i]+" ");
    }
    System.out.println("共耗时:"+(endTime-startTime)+"毫秒");
}

代码简述

再次注意:这个有序表和无序表是我们想象出来的,并不真实存在

1.首先我们要明确,我们需要遍历的是无序列表,而非有序列表,因此我们for循环应该从1开始

2.那么我们有序列表的最后一个元素的索引值(Length-1)就应该是当前循环的次数i-1(当前循环次数也就是当前有序列表的长度)

3.因此我们对有序列表从后往前循环,直到循环到索引值为0的位置,或者有序列表的当前元素比我们要添加的这个元素还要小(大)为止=>由此得出了我们的while循环条件;

4.那么在while循环体内,也就是有序列表当前位置元素大于要添加的这个元素,那么我们就将有序列表中的这个元素后移;

5.然后让有序列表的索引值往前移动一位(自减一);

6.当跳出while循环之后,才说明真正找到了索引值;

7.最后完成这一轮的添加;

特点

在每次判断对比之后只会让原来的元素往后移动一位,并且让索引值自减

在找到最终的索引时(也就是跳出while循环后)才会将当前元素添加进去,而不是在判断之后就立刻交换位置

效果展示

 性能测试

我们发现插入排序依旧是嵌套了两层循环,次数也是随着数组容量n的增大而增大,因此插入排序算法的时间复杂度依旧是O(n^2),我们还是初始化50000大小的随机数数组,来计算它的耗时,我们可以发现,它的速度甚至比选择排序还要快

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Strine

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值