写在前面:
简单插入排序法其实比较好理解,他的算法过程类似于打扑克抓牌的过程。在我们抓到第一张牌之后,以后抓的每一张牌都会与之前手中的牌对比,对比之后,插入到合适的位置上,直到抓完最后一张牌。那么在算法实现中,也是同理,我们假设数组索引为0的元素有序,从数组索引为1的元素开始,将arr[1]与arr[0]对比,如果大于arr[1]>arr[0],则插入到arr[0]的后面,如果arr[1]<arr[0],则插入到arr[0]的前面,依次类推。
例如:数组int [] arr = new int [] {2,5,3,1,6,8,4,7},第一个元素为2,默认就是有序的
- 第一次插入:插入元素5,比较后,插入到2的后面 -----[2,5] , 3, 1,6,8,4,7
- 第二次插入:插入元素3,比较后,插入到2的后面,5的前面-----[2,3 , 5] , 1,6,8,4, 7
- 第三次插入:插入元素1, 比较后,插入到2的前面 -----[1,2,3,5] ,6,8,4,7
- 第四次插入:插入元素6,比较后,插入到5的后面 -----[1,2,3,5,6] ,8,4,7
- 第五次插入:插入元素8,比较后,插入到6的后面 -----[1,2,3,5,6,8] ,4,7
- 第六次插入:插入元素4,比较后,插入到3的后面,5的前面-----[1,2,3,4,5,6,8] ,7
- 第七次插入:插入元素7,比较后,插入到6的后面,8的前面-----[1,2,3,4,5,6,7,8]
无论顺序如何,都会经历8-1次,这样经过了n-1次插入,就完成了简单插入排序。
代码实现:
package test2;
/**
* 简单插入排序
*
* @ClassName Test2
* @Description
* @author McGRADY
* @date 2018年3月8日
*/
public class Test2 {
public static void main(String[] args) {
int[] arr = new int[] { 7, 4, 2, 1, 5, 6, 3, 8 };
sort(arr);
for (int i : arr) {
System.out.print(i + ",");
}
}
public static void sort(int[] arr) {
int temp;
// 总计插入n-1次
for (int i = 1; i < arr.length; i++) {
temp = arr[i];
int j;
for (j = i - 1; j >= 0; j--) {
if (arr[j] > temp) {
arr[j + 1] = arr[j];
} else {
break;
}
}
arr[j + 1] = temp;
}
}
}
时间复杂度分析:
通过上面的实例分析,我们可以看出,无论数组的顺序如何,最后都要执行插入,也就是赋值语句arr[j+1]=temp,所以执行了n-1次。
而数组的移动次数则与数组的初始顺序有关。当数组正序的时候,数字移动次数为0.而当数组逆序的时候,交换次数(n-1)+(n-2)+......+1次,也就是=n*(n-1)/2次。
那么,最好情况下:程序会执行(n-1)+0 次,时间复杂度为O(n).
那么,最坏情况下:程序会执行(n-1)+n*(n-1)/2次,时间复杂度为O(n^2).
空间复杂度分析:
通过上面的实例分析,我们可以看出,简单插入排序只是定义了一个变量temp,空间复杂度为常量,即O(1)