关于排序算法请看我的第一篇文章(冒泡排序)。
首先介绍一下插入排序各项数据:平均/最坏时间复杂度O(n²),空间复杂度O(1),稳定性:稳定。
一、插入排序的设计思路
插入排序的思路从名字也是能够听出个大概的,就像插扑克牌一样,将数字按照一定顺序,一个一个的插入到指定位置。单从文字可能很难理解,我们上图说话。
首先有一个数组:
8 | 5 | 9 | 6 |
整个数组就相当于打扑克时候的牌堆,左面绿色的部分相当于我们手里的牌,第一张摸到8,因为手里没有牌所以直接放到手里就好。
8 | 5 | 9 | 6 |
从牌堆里摸一张牌,5,准备将它插入到手里的牌中,这时我们为了保证手里的牌是有序的,我们从右向左一个一个与5相比较,如果这张牌比5大那么就将它和5交换,直到5交换到第一的位置,如果不比5大,那么就证明5已经到了它应该在的位置了,我们手中的牌已经是有序的了,继续从牌堆里抓拍即可。
5 | 8 | 9 | 6 |
8比5大,8与交换,5到第一的位置了,结束插入,继续摸牌。
5 | 8 | 9 | 6 |
摸到一张9。
5 | 8 | 9 | 6 |
8不比9大,结束插入,继续摸牌。
5 | 8 | 9 | 6 |
摸到一张6。
5 | 8 | 6 | 9 |
9比6大,交换9与6的位置。
5 | 6 | 8 | 9 |
8比6大,交换8与6的位置。
5 | 6 | 8 | 9 |
5不比6大,结束插入,牌堆里没有牌了,这时我们就得到了一个有序数组。
二、插入排序的实现
老规矩,把问题拆分成小块,分别解决,首先我们解决单次插入,既根据一个给定的数字,插入到排好顺序的数组中:
int[] arr = new int[]{5,7,9,6};//定义数组,5,7,9是排好顺序的,把6插入进去
for(int i = 3 ; i > 0 ; i--){//自然是要插入谁就从谁开始
if(arr[i - 1] > arr[i]){//前一个数与它比较,如果大于就交换,因为这个循环就是一个一个往前遍历的,所以不需要操作指针
/**
* 交换
*/
int num = arr[i];
arr[i] = arr[i -1];
arr[i -1] = num;
}else{
break;//如果不大于就结束这次插入
}
}
//打印结果
for (int out: arr) {
System.out.print(out + " ");
}
实现单次插入以后,我们就要解决从哪里开始到哪里结束的问题,这里我们从下标1开始,因为下标0也就是第一个数不需要插入,只有他自己必然是有序的,每次抓一张牌就是每次加一,到最后一个数结束,就像摸牌必然要摸到最后一张。过于简单这里不放程序了,就是从1到数组结束。
最后我们代入上面的单次插入:
int[] arr = new int[]{6,7,2,3,5,1,4,8,9};//定义数组
for(int j = 1;j < arr.length ; j++){//从1开始一直到数组最后一位
for(int i = j ; i > 0 ; i--){//自然是要插入谁就从谁开始
if(arr[i - 1] > arr[i]){//前一个数与它比较,如果大于就交换,因为这个循环就是一个一个往前遍历的,所以不需要操作指针
/**
* 交换
*/
int num = arr[i];
arr[i] = arr[i -1];
arr[i -1] = num;
}else{
break;//如果不大于就结束这次插入
}
}
}
打印结果:1 2 3 4 5 6 7 8 9;没有问题~