1、排序原理
插入排序是将数组中的数据分为两个区间,已排序区间和未排序区间,其中已排序区间初始只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序。重复这个过程,直到未排序区间中元素为空,算法结束。通过一张动态图,来直观感受一下,要排序的数组为:[4,5,6,1,3,2],正序排序
1.1、排序过程详解
要排序的数组为:[4,5,6,1,3,2] ,假设 a为已排序区间,b为未排序区间,初始a=[4] ,b=[5 ,6, 1, 3, 2]
第一次遍历未排序区间:
未排序区间中的 5 依次与已排序区间中的数据[4]比较
- 5和4比较,5大于4,不进行数据移动,结束此次遍历。此时排序区间 a=[4,5] 未排序区间b=[ 6, 1, 3, 2],结果:[4,5,6,1,3,2]
第二次遍历未排序区间:
未排序区间中的 6 依次与已排序区间中的数据[4,5]比较
- 6和5比较,6大于5,不进行数据移动,结束此次遍历。此时排序区间 a=[4,5,6] ,未排序区间b=[ 1, 3, 2],结果:[4,5,6,1,3,2]
第三次遍历未排序区间:
未排序区间中的 1 依次与已排序区间中的数据[4,5,6]比较
- 1和6比较,1小于6,进行数据移动,结果:
[4,5,1,6,3,2]
- 1和5比较,1小于5,进行数据移动,结果:
[4,1,5,6,3,2]
- 1和4比较,1小于4,进行数据移动,结果:
[1,4,5,6,3,2]
,此时1在已排序区间中找到合适的插入位置,此时排序区间a=[1,4,5,6]
,未排序区间b=[3, 2]
第四次遍历未排序区间:
未排序区间中的 3 依次与已排序区间中的数据[1,4,5,6]比较
排序后结果:[1,3,4,5,6,2]
,此时排序区间 a=[1,3,4,5,6]
,未排序区间b=[ 2]
第五次遍历未排序区间:
未排序区间中的 2 依次与已排序区间中的数据[1,3,4,5,6]比较
排序后结果:[1,2,3,4,5,6]
,此时排序区间 a=[1,2,3,4,5,6]
,未排序区间为空b=[ ]
,排序结束
2、代码实现
明白了上面的原理,代码实现起来就容易多了
/**
* 插入排序
* @param arr
* @return
*/
public static int[] insertionSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
//待排序元素
int value=arr[i];
//已排序元素下标
int insertIndex=i-1;
//使用待排序元素依次与已排序区的元素相比较
while (insertIndex>=0&&value<arr[insertIndex]){
arr[insertIndex+1]=arr[insertIndex];
insertIndex--;
}
//把当前未排序数据插入到已排序区间
arr[insertIndex+1]=value;
}
return arr;
}
3、算法分析
3.1、时间复杂度
- 最好情况:T(n)=O(n)
- 最坏情况:T(n)=O(n^2)
- 平均情况:T(n)=O(n^2)
3.2、是否稳定
在插入排序中,对于值相同的元素,我们可以选择将后面出现的元素,插入到前面出现元素的后面,这样就可以保持原有的前后顺序不变,所以插入排序是稳定的排序算法。