插入排序 Insert Sort
- 插入排序的思想:
將一個待排序的無序的數組看作是兩個列表,一個有序的列表,一個無序的列表,從無序的列表每次拿出一個待插入的元素,插入到有序的列表中,直
到無序列表爲空,排序完畢
- 實際舉例:
-
有一個無序的一維數組是這次需要排序的數組,數組是:
[36,12,96,-1]
-
首先把數組的第一個元素
[36]
看作是一個獨立的有序的列表,把剩下的元素[12, 96, -1]
看作是一個無序的列表 -
第一個待插入的元素就是
12
,要把12
插入到有序的列表中,首先需要12
和36
比較,如果帶插入的元素12
小於36
,就需要把12
插入到36
前面,也就是36
要後移一位。 -
插入排序實際是需要比較數組元素的總數減一輪,因爲第一個元素不需要比較。
$arr = [36,12,96,-1];
//待插入的數
$insertValue = $arr[1];
//待插入數前面的數的索引
$insertIndek = 1 - 1;
//$insertIndek >= 0 保證插入循環時,不越界,保證第一個元素的下標要大於等0
//$insertValue < $arr[$insertIndek] 保證待插入的數還沒有找到插入的位置,即待插入的數是小於它前面的那一個元素的
//符合上述條件的,需要將$arr[$insertIndek] 後移
while($insertIndek >= 0 && $insertValue < $arr[$insertIndek]) {
$arr[$insertIndek+1] = $arr[$insertIndek];
$insertIndek--;//代表的就是有序列表的最前面一個元素的前面一個下標 -1;
}
//當退出循環時,代表找到位置 $insertIndek + 1
$arr[$insertIndek + 1] = $insertValue;//把插入的元素插入到有序列表的第一個位置或者是沒發生交換就在本身的位置
$arr = [12,36,96,-1];
//待插入的數
$insertValue = $arr[2];
//待插入數前面的數的索引
$insertIndek = 2 - 1;
//$insertIndek >= 0 保證插入循環時,不越界,保證第一個元素的下標要大於等0
//$insertValue < $arr[$insertIndek] 保證待插入的數還沒有找到插入的位置,即待插入的數是小於它前面的那一個元素的
//符合上述條件的,需要將$arr[$insertIndek] 後移
while($insertIndek >= 0 && $insertValue < $arr[$insertIndek]) {
$arr[$insertIndek+1] = $arr[$insertIndek];
$insertIndek--;//代表的就是有序列表的最前面一個元素的前面一個下標 -1;
}
//當退出循環時,代表找到位置 $insertIndek + 1
$arr[$insertIndek + 1] = $insertValue;//把插入的元素插入到有序列表的第一個位置或者是沒發生交換就在本身的位置
-
依次類推,得到完成的有序數組
-
完整代碼如下:
<?php
class InsertSort
{
public static function insertArraySort(array $data):array
{
if (!is_array($data)) {
return ['message' => '待排序的序列非數組'];
}
$count = count($data);
if ($count <= 1) {
return $data;
}
for ($i = 1; $i < $count; $i++) {
//待插入的元素
$insertValue = $data[$i];
//待插入數前面的數的索引
$insertIndek = $i - 1;
//$insertIndek >= 0 保證插入循環時,不越界,保證第一個元素的下標要大於等0
//$insertValue < $arr[$insertIndek] 保證待插入的數還沒有找到插入的位置,即待插入的數是小於它前面的那一個元素的
//符合上述條件的,需要將$arr[$insertIndek] 後移
while($insertIndek >= 0 && $insertValue < $data[$insertIndek]) {
$data[$insertIndek+1] = $data[$insertIndek];
$insertIndek--;//代表的就是有序列表的最前面一個元素的前面一個下標 -1;
}
//當退出循環時,代表找到位置 $insertIndek + 1
//把插入的元素插入到有序列表的第一個位置
//或者是沒發生交換,即待插入元素大於有序列表的最後一個元素,那麼這裏只需要將有序列表的最後一個元素的索引 + 1,把待插入元素放在後
//面一位即可
$data[$insertIndek + 1] = $insertValue;
}
return $data;
}
}
$arr = [36,12,96,-1];
var_dump(InsertSort::insertArraySort($arr));