直接插入排序
基本思想
所謂插入排序,顧名思義,就是每次將數字插入到有序序列當中,使得新的序列依然有序。即:將原序列分爲兩個序列,一個序列是有序序列,一個序列爲無序序列。假設一共有n個無序數,那麼,我們第一次選擇一個數據元素作爲有序序列(我們知道,一個元素本身肯定是有序的),將其他n-1個元素都作爲無序序列,那麼,我們每一次從無序序列中取出一個數,通過某種方法找到合適的位置插入,這樣,有序序列的元素總數就多了一個,無序序列的元素總數就少了一個。通過n-1次放置之後,就可以得到數據元素總數爲n的有序序列了,排序完成。
那麼,我們如何通過上述方法,在有序序列中找到合適的位置插入待排序的元素呢?我們可以先記錄下這個數A,然後,從後往前開始找,如果連續的兩個都比A要大,那麼,這個數肯定在這兩個數的前面,所以我們把這兩個數後移。依次進行,如果找到兩個數一個大於A,一個小於A,那麼直接將這個數放到中間即可。
操作方法
假設有一組無序序列 R0, R1,…, RN-1。
(1)我們先將這個序列中下標爲 0 的元素視爲元素個數爲 1 的有序序列。
(2) 然後,我們要依次把 R1, R2,…, RN-1 插入到這個有序序列中。所以,我們需要一個外部循環,從下標 1 掃描到 N-1 。
(3) 接下來描述插入過程。假設這是要將 Ri 插入到前面有序的序列中。由前面所述,我們可知,插入Ri時,前 i-1 個數肯定已經是有序了。
所以我們需要將Ri 和R0 ~ Ri-1 進行比較,確定要插入的合適位置。這就需要一個內部循環,我們一般是從後往前比較,即從下標 i-1 開始向 0 進行掃描。
算法實現(Java)
// 直接插入排序算法
publicstaticvoid insertSort(inta[]) {
for (inti = 1; i< a.length; i++){
// 待插入元素
inttemp= a[i];//記錄待插入元素的值
intj;//尋找到的下標
for (j= i - 1; j >= 0; j--){
if (a[j] > temp){
a[j+ 1] = a[j];
}else//找到了一個小於等於待插入元素的元素,跳出
break;
}
a[j+ 1] = temp;//將待插入元素插入到尋找到的元素的下一位
}
}
效率分析
算法性能:
時間複雜度:
數據基本有序時,效率最高,每次插入幾乎不用移動前面的元素,時間複雜度爲O(N)。
數據基本逆序時,效率最低,每次插入幾乎都要移動前面的元素,時間複雜度爲O(N2)。
所以,數據越接近有序,直接插入排序的算法性能越好。
空間複雜度
由直接插入排序算法可知,我們在排序過程中,需要一個臨時變量存儲要插入的值,所以空間複雜度爲 1。
算法穩定性
直接插入排序的過程中,不需要改變相等數值元素的位置,所以它是穩定的算法。