插入排序
1.定義:
(1)插入排序類似於咱們日常打撲克的時候,通常我們給牌排序時,總是將一張牌插入到其他已經有序的排中的適當位置。
(2)由(1)可知,插入排序是通過遍歷數組,並將當前元素與前面已經排好序的元素一一比較,獲得最佳位置
(3)爲了給要插入的元素騰出空間,需要將其餘所有元素在插入之前都向後移動一位。
(4)與選擇排序一樣,當前索引左邊的所有元素都是有序的,但它們的最終位置還不確定。
2.代碼剖析
假設:數組a,長度n,下標i
(1)數組從小到大遍歷。
(2)當下標索引爲 i 時,比較 a[i] 與 a[i-1],若前者小於後者,則交換兩個元素的位置,之後讓 i--。
(3)循環第二步的操作,直到 a[i]>a[i-1],這時肯定是不交換位置了的,於是,a[i]的這個元素就已經找到了合適的位置了。
(4)如此往復,直到整個數組遍歷結束。
3.圖解
我們可以看出,首先,數組的第一位我們可以直接跳過不用做判斷處理;其次,要等到算法跑完後,其元素的位置最終才定下來。其當前元素只要一判斷到不符合條件就直接跳過進入下一個元素判斷了,還是比較乾脆的。
4.按照這個思路,寫出代碼如下:
/**
* 插入排序
* 排序過程:
* 1.數組從小到大遍歷
* 2.將當前遍歷到的元素插入到前面已經排序好的數組裏
* 3.插入進去後,其他元素向後排序
* 4.如此往復,直到整個數組排序
* @param array
*/
public static void insertSort(int[] array) {
//將array[]按升序排序
int N = array.length;
int t;
for (int i = 1; i < N; i++) {
//將array[i]插入到a[i-1]、a[i-2]、a[i-3]...之中
//將當前元素與前一個元素相比較,若小於,則往前置換,否則不動
for (int j = i; j > 0 && array[j] < array[j - 1]; j--) {
t = array[j];
array[j] = array[j - 1];
array[j - 1] = t;
}
}
}
5.算法優劣判斷
(1)對於隨機排列的長度爲N且主鍵不重複的數組,平均情況下插入排序需要N*N/4次比較以及N*N/4次交換。最壞情況下需要N*N/2次比較和N*N/2次交換,最好情況下需要N-1次比較和0次交換
(2)適合的用該算法的數組:數組中每個元素距離它的最終位置不遠;一個有序的大數組接一個小數組;數組中只有幾個元素的位置不正確。
(3)插入排序需要的交換操作和數組中倒置的數量相同,需要的比較次數大於或等於倒置的數量,小於等於倒置的數量加上數組的大小再減一。(倒置:指的是數組中的兩個順序顛倒的元素)
6.資料引用:
《算法Algorithms(第4版)》 p157~p159