PHP 排序演算法之插入排序

echo_dump發表於2019-12-08

插入排序 Insert Sort

  • 插入排序的思想:

將一個待排序的無序的陣列看作是兩個列表,一個有序的列表,一個無序的列表,從無序的列表每次拿出一個待插入的元素,插入到有序的列表中,直
到無序列表為空,排序完畢

  • 實際舉例:
  1. 有一個無序的一維陣列是這次需要排序的陣列,陣列是:[36,12,96,-1]

  2. 首先把陣列的第一個元素 [36] 看作是一個獨立的有序的列表,把剩下的元素 [12, 96, -1]看作是一個無序的列表

  3. 第一個待插入的元素就是 12,要把12插入到有序的列表中,首先需要1236比較,如果帶插入的元素12小於36,就需要把12插入到36
    前面,也就是36要後移一位。

  4. 插入排序實際是需要比較陣列元素的總數減一輪,因為第一個元素不需要比較。

$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;//把插入的元素插入到有序列表的第一個位置或者是沒發生交換就在本身的位置
  1. 依次類推,得到完成的有序陣列

5. 完整程式碼如下:

<?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));
本作品採用《CC 協議》,轉載必須註明作者和本文連結
LIYi ---- github地址

相關文章