插入排序着实让我映像深刻,初学时被坑了一把,我看到有的博客说是生成一个新的有序数组,然后循环把待排序数组的每个元素拿去跟有序的比较,找到合适的位置插入
对于这种坑爹博客,我只想说:耗子尾汁!
首先讲整体思路:
把待排序数组切成两部分两个队伍(良民与暴徒),一段是已经排好序的(良民队伍),一段还是乱序的(暴徒队伍),不断拿乱序那边的元素让它在有序的那一段找到最合适自己的位置,让它从乱序变有序,这个动作可以看成是让暴徒找准自己的社会定位,成为对社会有价值的良民,从而感化他
那么故事就开始了~
(1)混沌之初,一个数组全是乱序的,每个元素乱七八糟毫无规矩可言
(2)这个时候,第一位的元素,也就是下标为0那个,觉悟了,他觉得是时候让这无序的数组变得有序!于是他从自己做起!成为良民阵型中的第一人!此时,一个数组内割裂开了两种阵型
(3)下标为0的元素鼓动下标为1的加入自己,于是两者比较一下大小,找到对应的位置重新排序
(4)这个时候良民阵型扩大了,暴徒阵型减少了一员
(5)每一个被感化的暴徒,都善意地与每一个有序数组段的元素比较大小(先从距离它最近的有序数组段元素比较,然后递减,直到下标小于0,也就是穷尽最后一个有序元素),如果小,就让身旁左边那个大的元素占了自己的位置,然后继续往前找。如果大,就说明自己比有序数组的最大一个元素都大,那就乖乖排在最后一位
(6)于是有序段这边的良民,一个接一个不断感化他们身旁右边的暴徒阵型,直到把全部暴徒都感化了,都成为有序阵型中的一员,无序段数组消失殆尽,整个数组变得井然有序,重获新生
可以看到,从始至终,都是在一个数组内做的操作,只不过是不断交换位置,使得无序变有序
牢记上面的步骤,下面看代码实现,保证能理解:
private static int[] insertSort2(int[] array) {
int i ;
// 默认第一个是已经排好序的,从第二个开始拿出每一个元素比较大小
for (int j = 1; j < array.length; j++) {
int tmp = array[j];
// 默认从j往前的数据都是排序好的,所以要跟排序好的那些数据倒着过去一个个比较,一直比较到下标为0的位置
// 记住这个for的条件还有一个,就是array[i]>tmp; 也就是良民比暴徒数值大,感化的暴徒就继续--往前面找到自己对应的位置
for (i = j-1; i >=0 && array[i]>tmp; i--) {
// 把i下标大的那个数覆盖到j那个位置,也就是前移了一位
array[i+1]=array[i];
}
// 跳出循环就表示array[i]元素小于tmp,这个时候前面的array[i]小于tmp,但是tmp屁股后面的数据又大于tmp,
// 所以也就是在有序数据中找到了最合适的位置,所以安心的把tmp放到对应i+1的位置
array[i+1] = tmp;
}
return array;
}
main方法
public static void main(String[] args) {
int[] messyArray = new int[]{6,1,4,3,2,7,9,0};
int[] sortArray = insertSort2(messyArray);
System.out.println(ArrayUtil.toString(sortArray));
}