直接插入排序
一、工作原理
第一步:我们选取目标数组
$arr = [5,2,6,0,3,9,1,7,4,8];
第二步:我们将5和2进行对比,我们的后一个元素要小于前一个元素,这样才能进行指针的移动,也就是$arr[$i] < $arr[$i - 1]的时候,这个时候就是将2放在临时变量也就是哨兵,然后对这个数组进行指针的移动;
$temp = 2; $arr = [5,2,6,0,3,9,1,7,4,8]; //变化后的数组 $arr[2,5,6,0,3,9,1,7,48];
这个时候我们就完成了第一轮的循环;
第二步:我们进行第二次的循环,一次重复上面的步骤就得到了;
图解
二、源代码
<?php function InsertSort(array &$arr) { $length = count($arr); for($i = 1; $i < $length; $i++){ if($arr[$i] < $arr[$i - 1]){ $temp = $arr[$i];//哨兵值,原理就是我们将要交换的值放在缓冲区; for($j = $i - 1; $arr[$j] > $temp; $j--){//进行指针的移动 $arr[$j+1] = $arr[$j]; } $arr[$j+1] = $temp; } } var_dump($arr); } $arr = [5,2,6,0,3,9,1,7,4,8]; InsertSort($arr);
注意:
1、我们第一次的循环是从1开始的,而不是0,原因就是为了后面的指针移动;
2、最重要的一点,当前一个元素比后一个大的时候才做指针的移动;
3、将目标数组排序成功就是靠一次次的指针移动。
三、性能分析
排序类别 | 排序方法 | 时间复杂度 | 空间复杂度 | 稳定性 | ||
平均情况 | 最坏情况 | 最好情况 | ||||
插入排序 | 直接插入排序 | O(n^2) | O(n^2) | O(1) | 稳定 |
希尔排序
一、工作原理
1、具体的工作原理
第一步:我们的目标数组是
$arr = [5,30,7,9,20,10]
第二步:我们以步长为三的开始进行对比,当前一个元素大于后一个元素的时候,开始进入直接插入排序算法,5和9进行对比,不满足不进行指针的移动,30和20相比,这个时候进行指针的移动,将30和20的位置互换;7和10比较不用互换,最后的数组为
$arr = [5,20,7,9,30,10]
第三步:我们将步长减小在对第二步进行操作,最终得出答案;
2、图解
二、源代码
<?php function InsertSort(array &$arr) { $length = count($arr); $gap = $length; do{ $gap = intval($gap/3 + 1);//设置比较两个值的步长,直接插入排序的步长是1 for($i = $gap; $i < $length; $i++){ if($arr[$i] < $arr[$i - $gap]){ $temp = $arr[$i];//哨兵值,原理就是我们将要交换的值放在缓冲区; for($j = $i - $gap; $arr[$j] > $temp; $j-=$gap){//将换值的指针后移 $arr[$j+$gap] = $arr[$j]; } $arr[$j+$gap] = $temp; } } }while($gap > 1); var_dump($arr); } $arr = [5,2,6,0,3,9,1,7,4,8]; InsertSort($arr);
注意:
1、希尔排序是在直接插入排序上面改进的,它主要做的就是步长的改变,上面的直接插入排序的步长就1;这个步长就是将数组分成几个小的数组,在对这几个小的数组进行直接插入排序。
三、性能分析
排序类别 | 排序方法 | 时间复杂度 | 空间复杂度 | 稳定性 | ||
平均情况 | 最坏情况 | 最好情况 | ||||
插入排序 | 希尔排序 | O(Nlog2N) | O(N1.5) | O(1) | 不稳定 |