Java常見排序演算法之插入排序

千鋒武漢發表於2021-04-12

一、概述

本節由小千給大家分享Java常見排序演算法之插入排序,之前我們說過排序是演算法中的一部分。所以我們學習排序也是演算法的入門,為了能讓大家感受到排序是演算法的一部分,我舉個例子證明一下:比如遊戲,發完牌之後需要對手上的牌進行排序,大家想想,排序如何排呢?它有什麼特點呢?而且在摸牌的過程中,我們要不斷的排序,如何排序呢?選擇什麼排序演算法最快呢?

以上這種情況我們就可以分析選擇哪種排序演算法更高效。比如下圖已經有一副固定順序的牌了:

Java常見排序演算法之插入排序

此時輪到我們摸牌,摸到的牌如下:

Java常見排序演算法之插入排序

此時,要將這個“三同”放到上面的一副牌中,就存在如下規律:

1、正常“3同”應該放到“2同”和”4同“中間。

2、跟其他花色的牌沒有關係,甚至跟”5同“也沒有關係。只需要把”3同“放到”2同“和”4同“中間就行。至於”2同”和”4同”在哪裡不要緊。

我們前面學習了選擇排序,如果使用選擇排序對上面這副牌進行排序是否合適呢?顯然是不合適的,因為選擇排序必須從“七萬”開始比較,選擇最小牌跟頭一張牌交換位置,依次類推。但是此處牌的“3同”跟”七萬“沒有關係,不需要影響”7萬“。所以使用選擇排序不合適,因為時間負責度很高;此處使用插入排序會更好,什麼是插入排序呢?就是本節需要介紹的內容。

二、插入排序

插入排序屬於簡單排序的一種,通常指的簡單排序只是因為其演算法思路比較容易理解,不代表其用途很簡單。為了讓大家掌握插入排序,我們先看看插入排序的原理。

2.1、插入排序的原理

首先有一個待排序的陣列如下:

Java常見排序演算法之插入排序

以上陣列中只有一個數字0的順序需要排列,其他數字的順序都是對的。這種陣列使用插入排序的效率更高,下面介紹此陣列使用插入排序的流程。

1、先比較1和2,如果2比1小則交換位置。否則不交換位置。此陣列不需要交換位置。

Java常見排序演算法之插入排序

2、再比較2和3,如果3比2小,則交換位置。但是實際3比2大所以不交換位置,保持不變。

Java常見排序演算法之插入排序

3、同理,3和4比較也不需要交換位置,保持不變

Java常見排序演算法之插入排序

4、接來下,4和0比較,0小於4,所以交換位置

Java常見排序演算法之插入排序

交換位置之後的陣列如下:

Java常見排序演算法之插入排序

5、因為3的鄰居發生變化,所以3和0再次比較,0比3小,交換位置,交換之後的陣列如下:

Java常見排序演算法之插入排序

6、依次類推,0分別和2交換位置之後的陣列如下:

Java常見排序演算法之插入排序

0再和1交換位置的陣列如下:

Java常見排序演算法之插入排序

這樣一個陣列的順序就對了,但是迴圈還沒有完成,因為我們剛才僅僅迴圈到數字4這個位置,數字5還沒有比較。

7、最後比較4和5,如果5比4小則交換位置,但是5比4大,所以位置不變。陣列迴圈完畢,最終排序如下:

Java常見排序演算法之插入排序

上面就是插入排序的原理。

2.2、插入排序和選擇排序的區別

比如就上面這個例子而言,插入排序是將0從索引為4的位置移動到索引3、2、1、0,最終才算結束。而選擇排序是找到最小的值0,直接跟1進行交換,0到1的位置,1到0的位置。大家可以翻看前面關於選擇排序的介紹。

三、插入排序的程式碼實現

以下是java程式碼的實現:

/**

* 插入排序

*/

public static void algorithm5(){

//原始陣列

int[] array={1,2,3,4,0,5};

//陣列的長度

int length=array.length;

//對陣列進行遍歷 for (int i = 0; i < length; i++) {

//第二個迴圈僅僅是將當前資料跟自己左邊的數字進行比較,如果小於左邊數字則交換位置,否則位置 不變。

for (int j = i; j > 0 && array[j]<array[j-1]; j--) {

int temp = 0;

temp = array[j-1];

array[j-1]=array[j];

array[j]=temp;

}

}

//將排好序的陣列列印輸出

for (int i = 0; i < length; i++) {

System.out.print(array[i]+",");

}

}

以上是插入排序的java程式碼實現,程式碼中的第二個for迴圈是重點,第二個for迴圈是隻比較當前資料左邊的值,如果比左邊的值小則交換位置,否則位置不變。

3.1 插入排序的時間複雜度

插入排序的時間複雜度有兩種:

1、當陣列本身是有序的,比如{1,2,3,4,5},則採用插入排序的時間複雜度是O(n)。原因:如果陣列本身是有序,插入排序需要每兩個挨著的數字進行比較一次,總共比較N-1次,所以時間複雜度是O(n)。

2、當陣列是無序的,最壞的情況下需要比較(n^2)/2次,所以時間複雜度是O(n^2)。

四、總結

根據插入排序的時間複雜度來看,插入排序適合如下型別的陣列:

1、陣列中的每一個元素距離其最終的位置都不遠。比如{1,0,2,3,4,5},這個陣列中0最終位置應該是頭1個位置,0此時的位置距離1位置不遠。

2、一個有序的大陣列中融入一個小陣列。比如有序大陣列{1,2,3,4,5,6},融入一個小陣列{0,1}。

3、陣列中只有幾個元素的位置不正確。

上述這三種情況的陣列適合使用插入排序演算法。打過的同學想想,過程中不停地摸牌、整理牌的過程是不是就是一次插入排序呢!

排序是演算法的基礎,排序的用途很多。看完本節內容之後,大家不妨自己動手寫個程式碼將無需的牌進行排序,看更適合哪種排序演算法。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31548651/viewspace-2767536/,如需轉載,請註明出處,否則將追究法律責任。

相關文章