排序算法之插入排序

插入排序一般分为 直接插入排序二分插入排序
一、直接插入排序:直接插入排序又可以分为前插和后插,不过虽然是这样分,只是寻找地点的方向不一样而已。“前插”就是从头开始找合适的位置,“后插”就是从后面开始找合适的位置。直接插入排序的思想很简单,开始时,整个数组都是无序的,默认第一个数是排好序的,然后要把第二个数插入到前面,那么就要找到合适的位置插入,从当前数的前一个数$a与当前数$s进行比较,如果此时$a<$s,那么就把$s插入到$a的后面,否则$s就与$a前面的数$b进行比较,或者$a已经是第一个数了就停止,把$s插入到数组的第一个位置。现在前两个数已经是有序的了, 然后就是插入第三个数,步骤是一样的。一个关键性的问题就是,循环停止的位置是要插入的位置的前一个,也就是说,应该从这个位置的后一个向后移动,腾出那个合适的位置。腾位置时应该是前一个数覆盖后一个数,所有for循环应该从后向前开始。
   1、前插:
         插入流程:
      初始状态:  (17) ,3 ,25 ,14 ,20, 9
      第一次插入:(3 , 17),25 ,14 ,20, 9
      第二次插入:(3 , 17, 25),14 ,20, 9
      第三次插入:(3 , 14, 17, 25),20, 9
      第四次插入:(3 , 14, 17, 20 ,25),9
      第五次插入:(3 , 9 ,14, 17, 20 ,25)
       代码实现:
<?php

/**
 * php 插入排序
 */
$arr = array(17,3 ,25,14,20,9);

function insertSort(&$arr) {
    //先默认第一个下标为0的数是排好的数
    for ($i = 1; $i < count($arr); $i++) {
        //确定插入比较的数
        $insertVal = $arr[$i];
        //确定与前面比较的数比较
        $insertIndex = $i - 1;

        //表示没有找到位置
        while ($insertIndex >= 0 && $insertVal < $arr[$insertIndex]) {
            //把数后移
            $arr[$insertIndex + 1] = $arr[$insertIndex];
            $insertIndex--;
        }
        //插入(给$insertval找到位置了)
        $arr[$insertIndex + 1] = $insertVal;
    }
}

insertSort($arr);
print_r($arr);
?>

 2、后插:

     插入流程:
    初始状态:  17,3 ,25,14,20,(9)
    第一次插入:3 ,17,25,14,(9,20)
    第二次插入:3 ,17,25,(9,14,20)
    第三次插入:3 ,14,(9,17,20,25)
    第四次插入:3 ,(9,14,17,20,25)
    第五次插入:(3 ,9,14,17,20,25)

    代码实现:

<?php

/**
 * php 插入排序 
 */
$arr = array(17,3 ,25,14,20,9);

function insertSort(&$arr) {
    $len = count($arr);
    //先默认第一个下标为len的数是排好的数 
    for ($i = $len - 2; $i >= 0; $i--) {
        //确定插入比较的数 
        $insertVal = $arr[$i];
        //确定与前面比较的数比较 
        $insertIndex = $i + 1;

        //表示没有找到位置 
        while ($insertIndex < $len && $insertVal > $arr[$insertIndex]) {
            //把数前移 
            $arr[$insertIndex - 1] = $arr[$insertIndex];
            $insertIndex++;
        }
        //插入(给$insertval找到位置了) 
        $arr[$insertIndex - 1] = $insertVal;
    }
}

insertSort($arr);
print_r($arr);
?> 

 二、二分插入排序:二分插入排序只不过查找的方式不同而已。每次要插入的值$a[$i]总是与前面已排好序的中间的值$a[$mid]进行比较,如果$a[$i]比较小则在前面的区间继续二分查找,否则在后面的区间。

<?php

/**
 * php 插入排序 
 */
$arr = array(12, 234, 33);

function binarySort(&$a) {
    $len = count($a);

    for ($i = 1; $i < $len; $i++) {
        $left = 0;
        $right = $i;
        while ($left <= $right) {
            $mid = intval(($left + $right) / 2);
            if ($a[$mid] > $a[$i]) {
                $right = $mid - 1;
            } else if ($a[$mid] < $a[$i]) {
                $left = $mid + 1;
            } else {
                break;
            }
        }
        //保存当前数据
        $s = $a[$i];
        //将数据向后移动
        for ($k = $i; $k >= $left; $k--) {
            $a[$k] = $a[$k - 1];
        }
        //将当前的数据放在找到的位置
        $a[$left] = $s;
    }
}

binarySort($arr);
print_r($arr);
?> 

 

 

转载于:https://www.cnblogs.com/solodance/p/3344629.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值