1.直接插入排序的基本思想:
假設待排序的記錄存放在數組R[1..n]中。初始時,R[1]自成1個有序區,無序區爲R[2..n]。從i=2起直至i=n爲止,
依次將R[i]插入當前的有序區R[1..i-1]中,生成含n個記錄的有序區。
待排序記錄 R1,R2,… ,Rn–1, Rn
第一步:R1
第二步:(R1 ), R2
第三步:(R1 , R2), R3
……
第 j 步:(R1,R2,… ,Rj–1), Rj
……
第 n 步: (R1,R2,… ,Rn–1), Rn.
例:j=5
原有序表中關鍵詞比Rj大的記錄數:dj
比較次數:dj+1 移動次數: dj+2
直接插入排序是由兩層嵌套循環組成的。外層循環標識並決定待比較的數值。內層循環爲待比較數值確定其最終位置。
直接插入排序是將待比較的數值與它的前一個數值進行比較,所以外層循環是從第二個數值開始的。當前一數值比待
比較數值大的情況下繼續循環比較,直到找到比待比較數值小的並將待比較數值置入其後一位置,結束該次循環。
2.直接插入排序的Java代碼實現
public class InsertSort {
public static void main(String[] args) {
int[] aa={8,4,6,1,9,3,25,14,18,16};
System.out.println("排序前:");
System.out.println(Arrays.toString(aa));
System.out.println();
insertSort(aa);
System.out.println("排序後:");
System.out.println(Arrays.toString(aa));
}
private static void insertSort(int[] aa) {
// TODO Auto-generated method stub
/*
for(int i = 1; i < aa.length; i++) {
int j = i - 1;
int temp = aa[i];//哨兵位
while (j >= 0 && temp< aa[j]) {
aa[j+1] = aa[j];//將大於temp的值整體後移一個單位
j--;
}
aa[j+1] = temp;
}
*/
for (inti = 1; i < aa.length; i++) {
int temp = aa[i];
for (int j = i - 1; j >= 0 && temp < aa[j]; j--) {
aa[j + 1] = aa[j];
aa[j] = temp;
}
}
}
}
運行結果如下:
排序前:
[8, 4, 6, 1, 9, 3, 25, 14, 18, 16]
排序後:
[1, 3, 4, 6, 8, 9, 14, 16, 18, 25]
3.直接插入排序的效率
空間:S(1),直接插入排序只需要一個輔助空間。
時間:排序的基本炒作爲,1.比較關鍵字的大小;2.移動記錄
最好情況:當記錄已經是有序而且序列就是所求順序的時候,第二個for循環將不會被運行,整體空間複雜度爲O(n)
最壞情況:當記錄和需要得出的序列剛好相反時,第二個for循環被執行的次數最多,比較次數爲(2,3,...,n)次,即(n+2)(n-1)/2,移動次數爲(2,3,...,n,n+1),即(n+4)(n-1)/2。
平均次數大約爲n2/4,即時間複雜度爲O(n2)