超详细推导八大排序之插入排序

插入排序思路:首先把一组数据分成两个部分,一部分是已经排好顺序的,这里我按照从小到大排列(这部分记作A),一部分是待排列数据(这部分记作B),默认排列好的部分只有一个数据也就是arr[0],然后将后面的数据依次与arr[0]比较,如果小于arr[0]则需要插入到arr[0]的前面(因为是从小到大的嘛)

没理解没关系,现在我举例详细说明:
在这里插入图片描述
如图,此时默认排列好的数据只有arr[0],除此之外都是待排数据.首先进行第一轮排序比较。这里的比较是从后向前比较,也就是从待排序元素后面的一个元素依次向前比较。arr1等于34小于arr[0],所以将34移到arr[0]后面。那么怎样移动呢?解决了这个,插入排序问题就迎刃而解了。

规则如下:
当前待插入的数据从它后面的一个元素依次向前比较,直到遇到了A部分有数据小于当前待插入的数据或者已经遍历到了开头arr[0],(因为再向前比较数据下标就越界了嘛)。此时就找到了插入的位置,接下来就是将遍历过的(A部分)元素全部向前移动一位(arr[pos + 1] = arr[pos]),也就是后面的元素覆盖前一个元素。所以经过移动过后,A部分肯定会空出一个位置,这个位置就是要插入的位置
。还是举例说明,如下图。
在这里插入图片描述
在这里插入图片描述
此时A部分有了两个排好的数据,接下来比较下一个待插入数据arr2。因为arr2 > arr2 - 1,按照从小到大的规则,所以不需要动。所以如图:
在这里插入图片描述
接着,待插入的元素成了arr3,然后遍历A部分的数据直到遇见小于arr3的元素,及为插入位置,或者遍历到了arr[0],此时就表示没有数据小于arr3,所以将遍历过的元素全部后移一位(arr[ops] + 1 = arr[ops]),经过后移之后arr[0]的位置就空出来,所以直接插入待插入的数据,(arr[0] = temp.这里的temp已经保存了arr3的数据),所以排列过后如图:
在这里插入图片描述
后面就不做推导了,相信你已经明白了整个过程,接下来给出完整的代码:

//插入排序方法
    private static void insertSort(int[] arr){
        //因为初始待插入数据是从arr[1]开始的,所以初始化i= 1;
        for (int i = 1;i<arr.length;i++){
            int temp = arr[i];//存储当前要插入数据的值
            int insertPos = i - 1;//当前待插入元素的前一个元素的下标
            //说明:
            //inserPos > = 0是防止## 标题数组下标越界
            //temp < arr[insertPos]及表示当前待插入元素的值小于前一个元素(已经排好的元素)
            //当temp > arr[insertPos]则表示从大到小排列
            while (insertPos >= 0 && temp < arr[insertPos]){
                arr[insertPos + 1] = arr[insertPos];//元素后移一位
                insertPos --;//因为while循环里,在没有找到插入条件或者没有遍历到arr[0],会将排好部分的元素依次向后移一位
            }
            //内存循环结束表示找到了插入位置
            //进行插入
            arr[insertPos + 1] = temp;
        }
    }

综上,就完成了插入排序的全部推导,通过分析不难发现,插入排序设计到了大量的移动操作,假设待插入数据的最后一个数据非常小,所以就必须将已经排好的数据全部向后移动一位,这样效率就很低,所以之后我会介绍插入排序的优化——Shell排序,Shell会在插入排序的基础上大大优化性能。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值