Java常見排序演算法之插入排序-簡單的效能優化技巧

小可奈的春天發表於2020-12-17

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

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

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

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

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

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

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

二、插入排序

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

2.1、插入排序的原理

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

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

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

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

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

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

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

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

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

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

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

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

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

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 http://www.xingkongmj.com/news/id/85.html< length; i++) {

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

}

}

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

3.1 插入排序的時間複雜度

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

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

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

四、總結

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

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

2、一個有序的大陣列中融入一個小陣列。比如有序大陣列{1,2,3,4,5,6},http://www.xingkongmj.com/news/id/87.html融入一個小陣列{0,1}。

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

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

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

越來越多的小夥伴考慮學習程式語言加入IT行業,有的小夥伴就會比較擔心Java效能優化太複雜,自己缺乏經驗,應付不來。不得不說,對於初入門Java的學員而言,優化應用程式以獲得最佳效能不是一件容易的事情。用情感性語言如何吸引讀者進行軟文推廣品牌營銷但是,這並不意味著如果你不具備這些知識,就不能做任何事情。今天給大家介紹有關Java效能優化的小技巧。

1.在你確認必要之前不要優化

你應該遵循常見的最佳實踐做法並嘗試高效地實現用例。但是,這並不意味著在你證明必要之前,你應該更換任何標準庫或構建複雜的優化。在大多數情況下,過早優化不但會佔用大量時間,而且會使程式碼變得難以閱讀和維護。

2.使用分析器查詢優化的真正瓶頸

在你確定了應用程式的某些部分需要改進後,可以嘗試通過檢視你的程式碼,並從看起來可疑或者你覺得可能會產生問題的部分開始。品牌如何推廣哪些網路渠道可以進行推廣或者使用分析器並獲取有關程式碼每個部分的行為和效能的詳細資訊。這兩種方法來解決問題。

3.建立效能測試套件

這樣做的好處是可以幫助你避免在將效能改進部署到生產後經常會發生的許多意外問題。你應該總是定義一個測試整個應用程式的效能測試套件,並在效能改進之前和之後執行它。而且額外的測試執行將幫助你識別更改的功能和效能副作用,並確保不會導致弊大於利的更新。

4.儘可能使用基元

避免任何開銷並提高應用程式效能的另一個簡便而快速的方法是使用基本型別而不是其包裝類。所以,最好使用int來代替Integer,如何在網上推廣常見的方式有那些使用double來代替Double。這允許JVM將值儲存在堆疊而不是堆中以減少記憶體消耗,並作出更有效的處理。

5.快取昂貴的資源,包括資料庫連線

快取是避免重複執行昂貴或常用程式碼片段的流行解決方案。總的思路很簡單:重複使用這些資源比反覆建立新的資源要便宜。一個典型的例子是快取池中的資料庫連線。新連線的建立需要時間,如果你重用現有連線,則可以避免這種情況。

相關文章