希尔排序
希尔排序(Shell’s Sort)是 插入排序 的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序的最好时间复杂度O(n)和最坏时间复杂度O(n2)。想要理解希尔排序,首先得理解插入排序。
希尔排序是按照增量进行分组,然后对每一组,进行插入排序,使得每一组基本有序。
图解参考:
以下是希尔排序的php版本
<?php
ini_set("display_errors", "On");
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2021/4/7 0007
* Time: 下午 2:28
*
* 给定一个数组,内容都为数字
* 外层循环分隔整个数组为多个长度为增量(增量为整数,每次循环除以2)的子序列
* 外层每分隔一次,内层从增量对应的键开始循环直到数组最后一位
* 与选择排序同理,如果 当前键位 – 增量 (也就是该子序列对应的另一个值)大于当前键位的值,插入当前键位到该子序列对应的另一个值左边(步长为增量)
* 继续按步长为增量进行累减(当前键位 – 增量 – 增量… )直到当前键位的值大于该子序列对应的另一个值
* 外层循环结束前已经是一个相对有序的数组了,最后一次循环步长为1,与正常选择排序相同
* 结束外层循环,得到一个升序数组
*
* https://zhuanlan.zhihu.com/p/56836177
*/
function donald_shell_sort($data){
$length = $num = count($data);
do {
$step = $num = intval($num/2); // step = 3
// 划分3组,[9,1] [4,6] [2,7]
// 对每组进行插入排序 : 将一个记录插入到已排好序的序列中,从而得到一个新的有序序列(将序列的第一个数据看成是一个有序的子序列,然后从第二个记录逐个向该有序的子序列进行有序的插入,直至整个序列有序
for ($i = $step; $i < $length; $i++) {
// 对第一组 [9,1]进行插入排序 ,由 9的下标0,1的下标3,
if($data[$i] < $data[$i-$step]){ // $data[3] < $data[0]
$min = $data[$i]; // 保存小的数(哨兵)
// $i = 3 ,$step = 3, j=0, 相当拿 $data[0] 和 $data[3] 对比
for($j = $i-$step; $j >= 0 && $min < $data[$j];$j -= $step){
// 往后排.
$data[$j+$step] = $data[$j ] ;
// 此时data = [9,9] 第一个9的下标是0,第二个下标是3(数据原来是1,被9覆盖)
}
// 此时 j = -1,最后将min放到最前面
$data[$j+$step] = $min;
// 此时data = [1,9]
// ... 再次循环 [4,6] ... [2,7]
}
}
}while ($step > 1);
return $data;
}
//function donald_shell_sort_2($array){
// $count_array = count($array);
//
//
// for($i = (int)($count_array/2);$i>0;$i=(int)($i/2)){ //循环分隔整个数组为多个长度为增量(增量为整数,每次循环除以2)的子序列
// for($j = (int)$i;$j<$count_array;$j++){ //从增量开始判断
// $index = (int)($j - $i); //步长为增量
// $current = $array[$j];
// while($index >= 0 && $array[$index] > $current){ //相对选择排序只是步长为增量而不为1
// $array[$index + $i] = $array[$index];
// $index = $index - $i;
// }
// $array[$index + $i] = $current;
// }
// }
//
// return $array;
//}
for ($i = 0 ; $i < 100000 ;$i ++){
$data[] = rand(0,9999);
}
echo json_encode(donald_shell_sort($data));exit;
参考文章:
https://www.cnblogs.com/chengxiao/p/6104371.html
https://zhuanlan.zhihu.com/p/56836177