思想
在已經排好序的數組上插入值,即選擇第一個數爲有序數組,
然後依次插入後面的數,如 6 4 5 7 0排序,選擇6爲有序數組,
依次插入4 5 7 0,其過程數組如下
6
4 5 7 0
4 6
5 7 0
4 5 6
7 0
4 5 6 7
0
0 4 5 6 7
.
插入排序過程有三種情況,
一種是插入的數值應該在原地(結尾),
一種插入的數值在應該中間,
一種插入的數值應該在開頭,
代碼
private int[] insertSort() {
if (this.arr.length < 2) {
return this.arr;
}
for (int i = 1; i<this.arr.length; i++) {
int tmp = this.arr[i];
if(this.arr[i] >= this.arr[i-1]) { // 原地不動
continue;
}
for(int j=i-1; j>=0; --j) {
this.arr[j+1] = this.arr[j];
if (tmp >= this.arr[j]) { // 插入中間位置
this.arr[j+1] = tmp;
break;
}
if (0 == j) { // 比第一個還小的情況
this.arr[j] = tmp;
}
}
}
return this.arr;
}
時間複雜度
按照代碼,最壞的情況(每次插入都遍歷一遍已經排好序的數組):
外層循環n-1次,內層循環1+2+3+…+(n-2)=(n-2)(n-1)/2次
所以最壞情況是O(n^2)
按照代碼,最好的情況(已經有序):O(n)
平均情況爲:(n^2 + n)/2,因爲二次函數比一元一次函數增長快,
所以爲插入排序算法的時間複雜度爲O(n^2)
空間複雜度
因爲輔助空間只有一個輔助變量,所以爲O(1)