插入排序【Java算法】

1. 概念

通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应的位置并插入。
插入排序非常类似于整扑克牌。在开始摸牌时,左手是空的,牌面朝下放在桌上。接着,一次从桌上摸起一张牌,并将它插入到左手一把牌中的正确位置上。为了找到这张牌的正确位置,要将它与手中已有的牌从右到左地进行比较。无论什么时候,左手中的牌都是排好序的。

2. 思路

① 把它想象成搬扑克牌,你首先搬到了第一张牌放到手里,接着你拿到了第二张牌,你要跟手里的第一张做一个比较,小的放左边大的放右边;

② 然后你又搬到了第三张牌,这时候我们一般是从右往左去观察手中的牌,一一与搬到的新牌作比较。当然,最先参与比较的一定是离它最近的那张牌(即第二张牌),如果新牌比第二张牌小,自然这个第二张牌是要向右移一位的(移了之后就不能叫它第二张了),如果新牌比第二张牌大,由于前面均已排好序,那么它就直接被放在了第二张牌的右边,结束比较;

③ 对应于程序,待排序数组我用 arr 来表示,当前待插入数据用 insertVal = arr[i] 表示,因为第一个数据是不需要进行比较的,所以这里的 i 从 1 开始,让 arr[1] 和 arr[0] 进行比较;

④ for 循环 i 的初始值为 1,每循环一次 i 就自增1,那结束状态呢?当走到最后一个数据的时候循环就到了尽头,而最后一个数据是 arr[arr.length - 1],所以这里的 i < arr.length;

⑤ 待插入数据要和谁来比较呢?初始情况下,肯定是跟它前面那一个数据进行比较,即 a[i - 1],在同一个待插入数据下,我们不太可能说只跟前一个数比较一下就完事了,往往还要跟前前个,前前前 … 个数据进行比较,也就是说这个被比较的数据,大概率是会改变的,所以,我这里用一个变量 index 来表示当前被比较数据的索引,i - 1 是初始情况下的值,在后续比较过程中,我们的 index 是会向左移动的,也就是以下代码中的 index–;

⑥ 由于待插入数据会从右往左不断地进行大小比较,而停止的具体位置我们也无法确定,那么这里,我们可以通过一个 while 循环来控制这个移动的动作;

⑦ 循环条件是什么呢?首先你既然要跟人家作比较,你必须得保证对方存在吧?不能说人家有都没有,你还隔这比较那就没有意义了。所以,这个被比较的数据索引一定要大于等于0(index >= 0),等于0的时候已经是尽头了,就不用再比较了啊。还有,如果说待插入数据比 arr[index] 要大,那么就没有必要循环下去了,直接把这个数据放到 index +1 位置即可。如果待插入数据比 arr[index] 小,就重复循环体中的动作,首先将 arr[index] 向后移一位(腾出位置),然后让 index 向前移一位(再跟下一位比较),一直重复,直到待插入数据比 arr[index] 大,才跳出循环;

⑧ 综上,我们的循环条件是 index >= 0 && insertVal < arr[index],循环结束之后,把待插入的数放入合适位置,index + 1 的位置。

3. 代码实现

public class Main {
    public static void main(String[] args) {
        int[] arr = {3, 2, 9, 11, 17, 4, 13, 7, 5, 1, 12};
        int[] newArr = sort(arr);
        for (int number : newArr) {
            System.out.print(number + " ");
        }
    }

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

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

栈老师不回家

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

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

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

打赏作者

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

抵扣说明:

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

余额充值