直接插入排序介紹
直接插入排序的基本操作是將一個記錄插入到已經排好序的有序表中,從而得到一個新的、記錄數增1的有序表。
怎么理解呢?就是將n個待排序的元素看成一個有序表和一個無序表,開始時有序表中只有一個元素,無序表中有n-1個元素,排序過程中每次從無序表中取出第一個元素,將其插入到有序表中的指定位置,使之成為一個新的有序表,重復n-1次可完成排序過程。
直接插入排序流程說明
具體流程如下:
- 首先比較數組的前兩個數據,並排序;
- 比較第三個元素與前兩個排好序的數據,並將第三個元素放入適當的位置;
- 比較第四個元素與前三個排好序的數據,並將第四個元素放入適當的位置;
… - 直至把最后一個元素放入適當的位置。
代碼實現:
public class InsertSort {
//置換
public void swap(int[] elem, int i, int j) {
int temp = elem[i];
elem[i] = elem[j];
elem[j] = temp;
}
public void insertSort(int[] elem) {
int i, j;
for (i = 2; i < elem.length; i++) {
if(elem[i] < elem[i - 1]) { //需要將elem[i]插入到有序子表
elem[0] = elem[i]; //設置哨兵
for (j = i - 1; elem[j] > elem[0]; j--) {
elem[j + 1] = elem[j]; //記錄后移
}
elem[j + 1] = elem[0]; //插入到正確位置
}
}
}
public static void main(String[] args) {
InsertSort s = new InsertSort();
// int[] elem = {0, 9, 1, 5, 8, 3, 7, 4, 6, 2};
int[] elem2 = {0, 5, 3, 4, 6, 2};
s.insertSort(elem2);
for (int i = 1; i < elem2.length; i++) {
System.out.print(elem2[i] + ", ");
}
}
}
i從2開始的意思是我們假設elem[1]=5已經放好位置,后面的數據元素就是插入到它的左側還是右側的問題。
對於初始數據:{5, 3, 4, 6, 2}。
- 首先比較5和3的大小,3小,位置互換,第一輪排序后,順序為:[3, 5, 4, 6, 2]。
- 對於第三個數據4,其大於3,小於5,將其插入3和5之間,順序依舊為:[3, 4, 5, 6, 2]。
- 對於第四個數據6,其大於3,4,5,不需要插入,位置不變,順序為:[3, 4, 5, 6, 2]。
- 對於第五個數據2,其小於於3,將其插入到3的前面,順序為:[2, 3, 4, 5, 6,]。
直接插入排序復雜度分析
從空間上看只需要一個哨兵的輔助空間。
當最好的情況下,也就是表本身就是有序的,那么我們比較次數共計n-1(
)次,因為每次都是elem[i]>elem[i -1],所以沒有移動記錄,時間復雜度為O(n)
當最壞的情況下,即逆序情況下,此時需要比較
次,而記錄的移動次數也達到最大值
次
如果排序記錄是隨機的,那么根據概率相同的原則,平均比較和移動次數約為
次。因此我們得出直接插入排序的時間復雜度為O(
)。
同樣的復雜度,直接插入排序比冒泡和簡單選擇排序性能要好。