简单插入排序改进:简单插入排序是将为排序队列中取一个值,插入到已排序序列的合适位置,如果数值较多,则在插入的时需要更多的时间,因此在寻找插入的合适位置时,使用二分查找方法,来减少插入时间。
二分查找查找到第一个大于待插入值得位置,
二分查找可以参考你真的会二分查找吗?
function insertsort(&$arr){
$len = count($arr);
for($i = 1;$i<$len;$i++){//未排序序列中取值
$tmp = $arr[$i];
$left = 0;
$right = $i-1; //设置二分查找的起始指针,终止指针。
while($left<=$right){ //此处必须为<=
$mid = ($left+$right)/2; //获取中点值。
if($arr[$mid]<$tmp){ //如果待插入的值大于中点值,
$left = $mid+1; //则左指针变更为中点値+1,防止死循环。
}else{
$right = $mid-1;
}
}
for($j = $i-1 ;$j>=$left;$j--){//将大于带插入的往后移动一位。
$arr[$j+1] = $arr[$j];
}
$arr[$left] = $tmp;
}
}
$arr = [9,8,7,6,5,4,3,2,1,3,1,4,2];
insertsort($arr);
echo '<pre>';
print_r($arr);
echo '<pre>';
希尔排序:缩小增量排序,
希尔排序是指,将数组分成按照增量为间隔的数组,每一组都按简单插入排序进行处理,随着增量的减小,在前一个增量的结果(间隔有序)上再次进行排序,直到增量为1时进行一次简单插入排序,算法终止。
function insertsort(&$arr){
$len = count($arr);
$h = 0;
while($h<$len){
$h=$h*3+1;//计算增量的值,1 4 13...,得到该数组下的最大增量值。
}
while($h>=1){//当增量等于1时,相当于简单插入排序。也是希尔排序的最后一次排序
for($i=$h;$i<$len;$i++){//因为$i为待排序值,从$h开始。
$tmp=$arr[$i];
for($j=$i-$h;$j>=0&&$tmp<$arr[$j];$j=$j-$h){//'$j'为已排序的下标,因为间隔为$h所以$i-$h.
$arr[$j+$h]=$arr[$j];
}
$arr[$j+$h] = $tmp;
}
$h = intval($h-1)/3;//减少增量的值。
}
}
$arr = [9,8,7,6,5,4,3,2,1,3,1,4,2,3,4,5,8,9];
insertsort($arr);
echo '<pre>';
print_r($arr);
echo '</pre>';