愚昧者怨天尤人,無能者長吁短嘆,儒弱者頹然放棄。
插入排序就是這麼容易
welcome rodert
一
插入排序(Insertion Sort)
各位工作了的大佬們,日常工作可能都使用各種類庫、工具,解決了需要解決的問題,一起來看看基礎算法。
一
介紹
【百度百科】:插入排序,一般也被稱爲直接插入排序。對於少量元素的排序,它是一個有效的算法。插入排序是一種最簡單的排序方法,它的基本思想是將一個記錄插入到已經排好序的有序表中,從而一個新的、記錄數增1的有序表。在其實現過程使用雙層循環,外層循環對除了第一個元素之外的所有元素,內層循環對當前元素前面有序表進行待插入位置查找,並進行移動。
實質:插入排序的代碼實現雖然沒有冒泡排序和選擇排序那麼簡單粗暴,但它的原理應該是最容易理解的了,因爲只要打過撲克牌的人都應該能夠秒懂。插入排序是一種最簡單直觀的排序算法,它的工作原理是通過構建有序序列,對於未排序數據,在已排序序列中從後向前掃描,找到相應位置並插入。
時間複雜度: O(N^(1-2))
一
實現
算法描述:
將第一待排序序列第一個元素看做一個有序序列,把第二個元素到最後一個元素當成是未排序序列。
從頭到尾依次掃描未排序序列,將掃描到的每個元素插入有序序列的適當位置。(如果待插入的元素與有序序列中的某個元素相等,則將待插入元素插入到相等元素的後面。)
動態圖演示:
選擇排序流程圖
圖片來源百度
Java代碼實現
@Test
public void insertionSort() {
int[] arr = {2, 0, 7, 3, 9};
for (int i = 1; i < arr.length; i++) {
// 記錄要插入的數據
int tmp = arr[i];
// 從已經排序的序列最右邊的開始比較,找到比其小的數
int j = i;
while (j > 0 && tmp < arr[j - 1]) {
arr[j] = arr[j - 1];
j--;
}
// 存在比其小的數,插入
if (j != i) {
arr[j] = tmp;
}
}
// 打印排序後結果
for (int i : arr) {
System.out.println(i);
}
}
優化
說明:
插入排序會將之前的所有的比它大的元素進行兩兩交換(從小到大排列的排序),會增加一些交換時間,降低運行效率,下面我們來討論一下它的優化算法,
不是進行兩兩交換,而是把當前待插入的元素取出,讓當前元素與之前的所有元素進行一一比較,前一個元素大於當前元素直接覆蓋,而到了最後當找到當
前元素的合適位置時只需要一次交換即可。
如序列:3 5 2 1 4
元素5先存入臨時變量temp中,跟前面元素比較,比前面元素大,然後拿出下一個元素2存入臨時變量temp中,2與前一個元素5比較,2比5小,用5直接覆蓋2
結果序列爲:3 5 5 1 4 temp=2,然後temp再與前一個元素3進行比較,發現2比3小,然後3再覆蓋剛纔的位置,序列爲3 3 5 1 4這時發現已經到序列的頭部了,
然後將temp=2複製給arr[0],就是直接覆蓋第一個元素3,序列變爲2 3 5 1 4,第一輪排序結束,跟直接插入排序太大的區別,只不過是減少了不斷交換的次數
用直接複製覆蓋取代,這樣當數據量特別大時效率就會提高很多。
@Test
public void insertionSort2() {
int[] arr = {3, 5, 2, 1, 4};
//排序
for (int i = 1; i < arr.length; i++) {//從第2個元素開始遍歷
int temp = arr[i];//將當前位置的元素取出
int j;
for (j = i; j > 0; j--) {
if (temp < arr[j - 1]) {//如果這個元素比temp大就覆蓋,否則就證明該元素之前已經有序就break
arr[j] = arr[j - 1];//直接用前一個元素進行覆蓋
} else {
break;
}
}
//將temp中的元素插入合適位置
arr[j] = temp;
}
// 打印排序後結果
for (int i : arr) {
System.out.println(i);
}
}
轉載是一種動力 分享是一種美德 開源是一種信仰
—END—
rodert
更多文章後面會持續分享,有特別需要可以提前留言。