8.3 直接插入排序

就如同拿到一摞乱扑克牌时候要在手里将顺序整理好一样,直接插入排序(Straight Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。

复杂度分析:

从空间来看,它需要一个记录的辅助空间O(n)(其实不需要也可以,直接在原数组中进行滑动操作,将目前要执行的元素current向前滑动到它对应的位置,此时不需要额外空间即O(1)),因此关键是看它的时间复杂度。当最好的情况,也就是要排序的表本身就是有序的,我们就相当于遍历了一遍数组,只是执行了大循环,内部小循环一直都未进行,而如果是最坏的情况,即排序表示逆序的,此时需要比较的次数就是 n * (n + 1)/2,需要移动的次数也是这些。如果排序记录是随机的,那么根据概率性相同的原则,平均比较和移动的次数约为 n * n / 4次。因此我们得出直接插入排序法的时间复杂度为O(n*n)。从这里可以看出,同样的O(n*n)的时间复杂度,直接插入排序法比冒泡法和简单选择排序法的性能要好一些。

下面看一下用php实现的该算法:

<?php
header("content-type:text/html;charset=utf-8");
/*
 * 插入法排序:
 * 每一个位置的值向前滑动,挨个与它之前的值进行比较,插到合适的位置
 * 时间复杂度:与数据情况有关
 * 最好的情况:O(N);
 * 最差的情况:O(N^2)
 * 额外空间复杂度O(1)
 * */

function insertSort($arr){
    if($arr == null || count($arr)<2){
        return true;
    }

    for($current=1;$current<count($arr);$current++){    //current为目前要进行插入操作的数字,0位置不需要再插入了,所以从1开始
        for($i = $current;$i>0 && $arr[$i-1]>$arr[$i];$i--){ //i>0保证往前滑比较的时候不越界,$arr[$i-1]>$arr[$i] 表示要进行插入操作的数字i与它前面的那个数进行比较,
                                                         //如果比它小就往前滑,所以执行i--,继续和它前一个数比较,直到插进适合它的位置
            swap($arr,$i-1,$i);
        }
    }
    return $arr;
}

function swap(&$arr,$i,$j){  //注意这里引用变量的使用

    $tem = $arr[$i];
    $arr[$i] = $arr[$j];
    $arr[$j] = $tem;
}

$arr = [2,33,45,22,64,67,12,1,0,9];
$array = insertSort($arr);
print_r($array);//结果:Array ( [0] => 0 [1] => 1 [2] => 2 [3] => 9 [4] => 12 [5] => 22 [6] => 33 [7] => 45 [8] => 64 [9] => 67 )

 

posted @ 2019-03-05 11:14  小林子奋斗的点滴  阅读(184)  评论(0编辑  收藏  举报