动画演示:
原理:
向已排好序的集合中插入元素,例如:身高从高到低排序一样(假设最后三是x,y,z),如果你想插队,你需要和z同学比较,如果你一些,z同学后退一位,你再次和y同学比较,如果还低一些,y同学后退一位,你再和同学比较,如果高一些,即排到x同学的后面
思路:
- 从第一个元素开始,该元素可以认为已经被排序;(i=0,1,2...length-2)
- 取出下一个元素,在前面已排序的元素序列中,从后向前扫描;(cur = arr[i+1])
- 如果该元素(已排序)大于新元素,将该元素移到下一位置;(cur < arr[preIndex] -> arr[preIndex + 1] = arr[preIndex] )
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
- 将新元素插入到该位置后;
- 重复步骤2~5
代码演示:
public class InsertSort {
public static void main(String[] args) {
int[]a = new int[]{2,6,3,4,9,8};
sort(a);
print(a);
}
private static void print(int[] arr) {
for(int i=0;i<arr.length;i++)
{
System.out.print(arr[i]+" ");
}
}
private static void sort(int []arr) {
if(arr == null || arr.length < 2){
return;
}
//已排序的数组索引(0,1,2...length-2的元素已排好序)
for(int i=0;i<arr.length-1;i++){
//当前需要插入的元素,保存(索引第1,2,3...length-1的元素)
int cur = arr[i + 1];
int preIndex = i;
//如果当前需要插入的元素较小,将较大元素向后移(覆盖)
while(preIndex >= 0 && cur < arr[preIndex]){
arr[preIndex + 1] = arr[preIndex];
//覆盖完成,向前一位再次比较(避免preIndex 越界,while条件限制preIndex >= 0)
preIndex--;
}
//插入的元素大于了preIndex,将元素插入到后面(preIndex + 1)的位置
arr[preIndex + 1] = cur;
}
}
}
平均时间复杂度:O(n²)
空间复杂度:O(1)
算法稳定性:稳定