插入排序
插入排序与选择排序一样,也分成:已排序列表 和 未排序列表 两部分。它也是重复执行一个步骤的过程:从右侧未排序列表取出第一个值,将它“插入”左侧已排序区域的合适位置,具体做法有不同的理解方式,比如:(方式一)先将它合并到左侧已排序列表的最右侧,然后针对已排序列表执行类似冒泡排序的过程
“从最右侧开始,依次比较相邻的两个元素的大小,右侧小于左侧则交换两者的位置,否则停止比较,看起来右侧的较小的数就好像渐渐浮到左边”
。(方式二)将从未排序列表取出的元素M
作为比较的标准,从已排序列表的右侧开始逐次取出值N
与M
进行比较,如果M < N
则继续取前一个值,当取出的值X
小于M
的时候,元素X
后面的位置就是插入M
的位置,在此过程中为了随时给M
留空,会将比较过的值依次往后移动。接下来以方式一进行插入排序的示意,其初始状态如图:
- 第一轮执行流程及结果:
- 第二轮执行流程及结果:
- 第三轮执行流程及结果:
- 第四轮执行流程及结果:
- 第五轮执行流程及结果:
- 第六轮执行流程及结果:
- 第七轮执行流程及结果:
- 第八轮执行流程及结果:
- 第九轮执行流程及结果:
Notice
:由于第1轮
其实只是起到了初始化的作用,并未产生任何的对比,所以示例的第1轮
可以忽略,实际执行了8轮
附
PHP
实现代码:
<?php
// 方式一
function insertSort1($arrayNeedsSort)
{
$length = count($arrayNeedsSort);
$arrReturn = [];
$arrReturn[] = array_shift($arrayNeedsSort);
for ($i = 0; $i < $length - 1; $i++) {
$compare = array_shift($arrayNeedsSort);
$arrReturn[] = $compare;
$jStart = count($arrReturn) - 1;
for ($j = $jStart; $j > 0; $j--) {
if ($arrReturn[$j] < $arrReturn[$j - 1]) {
$tmp = $arrReturn[$j - 1];
$arrReturn[$j - 1] = $arrReturn[$j];
$arrReturn[$j] = $tmp;
} else {
break;
}
}
}
return $arrReturn;
}
// 方式二
function insertSort2($arrayNeedsSort)
{
$length = count($arrayNeedsSort);
for ($i = 1; $i < $length; $i++) {
$compare = $arrayNeedsSort[$i];
for ($j = $i - 1; $j >= 0; $j--) {
if ($compare < $arrayNeedsSort[$j]) {
$arrayNeedsSort[$j + 1] = $arrayNeedsSort[$j];
$arrayNeedsSort[$j] = $compare;
} else {
break;
}
}
}
return $arrayNeedsSort;
}
$array = [5, 9, 3, 1, 2, 8, 4, 7, 6];
$res1 = insertSort1($array);
$res2 = insertSort2($array);
echo '<pre>';
print_r($res1);
print_r($res2);
运行结果:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
)
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
)