前言
可能按照 博文的小夥伴
已經發現了一個問題了,就是在特定情況下。插入排序
竟然比 選擇排序
的效能還要差。
大家不妨想一下,為什麼?
下面我們找幾個點進行優化
優化一哈
- 我們在
第二次迴圈
的時候 - 我們其實是可以把
判斷語句
放入到迴圈表示式
當中/** * 插入排序操作方法 - for * @param $sort * @param $n * @return mixed */ function get_insertion_sort_for_simple($sort,$n){ /** 將資料迴圈一次 */ for ($i = 0; $i < $n; $i++ ){ /** 將前面資料進行迴圈,並且帶上判斷的表示式*/ /** 把 判斷語句 放入到 迴圈表示式 當中 */ for($j = $i;$j > 0 && $sort[$j] < $sort[$j - 1]; $j--){ $val = $sort[$j]; $sort[$j] = $sort[$j - 1]; $sort[$j - 1] = $val; } } return $sort; }
執行後的懵逼
- 然後,大家發現
哦豁
- 這樣修改,有一定的優化程度,但是效果並不明顯
- 然後大家再想想,我們每次進行
位置交換
的時候,是不是需要進行一個以下操作 - 把需要
修改位置
的值,先賦值給一個新的變數
$val = $sort[$j];
- 再把
交換位置
的值賦值到修改位置
$sort[$j] = $sort[$j - 1];
- 再把
新的變數
,放入到交換位置
$sort[$j - 1] = $val;
- 一直這樣迴圈反覆的交換,需要的時間,其實是比
上面?
改表示式
好使的 - 因為我們每次交換,那必然是
三次賦值
- 那麼我們就有了以下思路
插入排序優化版,先簡單瞭解一下思路
- 首先我們有這麼一段資料,我們需要將他們重新整合有序
| 7 | 2 | 1 | 5 | 4 | 6 | 9 | 3 | 8 |
第一次排序
- 此時我們並不會去移動
7
,7
已然有序
| 7 | 2 | 1 | 5 | 4 | 6 | 9 | 3 | 8 |
第二次排序
- 我們繼續檢視數字座標
1
的數字 - 這次我們不直接和前面的
7
進行對比交換了 - 我們直接先把
2
複製出來一份,儲存成新的變數 - 然後我們再進行一個對比
- 顯然
2
比7
小,我們就將7
放在之前2
的位置 - 然後我們再對比陣列座標
0
的數字,但是此時已經是座標0
,所以我們直接放入即可
|2
|7
| 1 | 5 | 4 | 6 | 9 | 3 | 8 |
第三次排序
- 我們繼續檢視數字座標
2
的數字 - 我們還是先把
2
複製出來一份,儲存成新的變數,再進行對比 - 顯然
1
比7
小,我們就將7
放在之前1
的位置 - 然後再拿
1
和2
對比,1
比2
小,我們就將2
放在之前7
的位置 - 此時已經是座標
0
,所以我們直接放入即可
|1
|2
|7
| 5 | 4 | 6 | 9 | 3 | 8 |
第四次排序
- 我們繼續檢視數字座標
3
的數字 - 我們還是先把
5
複製出來一份,儲存成新的變數,再進行對比 - 顯然
5
比7
小,我們就將7
放在之前5
的位置 - 然後再拿
5
和2
對比,5
比2
大,我們就會跳出迴圈,然後放入即可
TimAutumnWind (轉載請註明出處 learnku.com/users/48310)
此後一直以此類推,直至到底
實現一下程式碼 - while
- 時間和效能記錄,可以參照章節中的
選擇排序
- 以後會直接實現程式碼
/** * 插入排序操作方法 - while * @param $sort * @param $n * @return mixed */ function get_insertion_sort_while_better($sort,$n){ $i = 0; while ( $i < $n ){ $j = $i; /** 拷貝複製一份 */ $e = $sort[$i]; while($j > 0 && $sort[$j - 1] > $e){ /** 將位置交出,往後挪一個位置 */ $sort[$j] = $sort[$j - 1]; $j--; } /** 跳出迴圈後,放入歸位 */ $sort[$j] = $e; $i++; } return $sort; }
本作品採用《CC 協議》,轉載必須註明作者和本文連結
TimAutumnWind (轉載請註明出處 https://learnku.com/articles/39442)