插入排序
方法
给定数组n,要求升序
一开始不看n[0]位置上的数,因为[0,0]位置上已经排好序了
接着考察n[1]位置上的数,比较n[0]和n[1],如果n[1]<n[0],就交换,否则不交换,[0,1]范围就排好了
接着考察n[2]位置上的数,比较n[1]和n[2],如果n[2]<n[1],就交换,否则不交换,然后再比较比较n[0]和n[1],如果n[1]<n[0],就交换,否则不交换,[0,2]范围就排好了
…重复以上步骤,
直到整个数组呈升序排列
规律就是
考察n[i]位置上的数,比较n[i-1]和n[i],如果n[i]<n[i-1],就交换,否则不交换,一直比较,直至n[i-j]和n[0]比较之后,就表示n[0,i]范围内已经排好序了
通俗来讲,打扑克,你已经抓了一把排好序的牌,然后你接了一张新牌,你就看这张牌可以插入哪里,这就是插入排序
代码实现
public class InsertionSort {
public static void sort(int[] arr){
//当数组长度为0或者1的时候,就没有必要排序,直接返回就行了
if (arr == null || arr.length < 2){
return;
}
//当前考察的是i位置的数,i就是新牌
for (int i = 1; i < arr.length; i++) {
//j位置和j+1位置上比较=>等同于i-1和i位置上的数进行比较
//只有j>=0并且j位置的数比j+1位置上的数大的时候,才交换两个数
//j--,就是如果j位置的数和j+1位置上的数交换了,那么j就来到了j-1位置
//就开始比较j-1和j-2的数,直到把区间内的数都比较完了
for (int j = i-1; j >= 0 && arr[j] > arr[j+1]; j--) {
ArraySwapTool.swap(arr,j,j+1);
}
}
}
}
时间复杂度分析
此时就需要考虑到时间复杂度中的最优情况,平均情况,最差情况
- 最优情况–数组是排好序的
- 这个最优情况对于冒泡和选择排序是没有什么影响的,因为他们的流程已经定好了,还是得一个一个比较,只是不交换罢了
- 但是对于插入排序来说,所有位置都不用交换,那么时间复杂度是O(n)
- 最差情况–数组是逆序的
- 对于插入排序来说,所有位置都需要交换,那么时间复杂度是O(n^2)