就如同拿到一摞乱扑克牌时候要在手里将顺序整理好一样,直接插入排序(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 )