直接插入排序(Straight Insertion Sort)是一种最简单的排序方法,其基本操作是将一条记录插入到已排好的有序表中,从而得到一个新的、记录数量增1的有序表。
直接插入排序的思想:每一趟将一个待排序的记录,按其关键字的大小插入到已经排好序的一组记录的适当位置上,直到所有待排序记录全部插入为止。直接插入排序引入了哨兵,设置监视哨是为了在查找插入位置的过程中避免数组下标出界。
直接插入排序的过程图:
直接插入排序的效率:
从空间上看,它只需要一个记录的辅助空间。
从时间上看,排序的基本操作为:比较两个关键字的大小和移动记录。
先分析一趟插人排序的情况。算法里层的for循环的次数取决于待插记录的关键字与前i-1个记录的关键字之间的关系。若L.r[]. key<L.r[1].key,则内循环中,待插记录的关键字需与有序子序列L.r[1..i-1]中i-1 个记录的关键字和监视哨中的关键字进行比较,并将L.r[1.i-1]中i-1个记录后移。则在整个排序过程(进行n-1趟插入排序)中,当待排序列中记录按关键字非递减有序排列(以下称为"正序")时,所需进行关键字间比较的次数达最小值n-1,记录不需移动;反之,当待排序列中记录按关键字非递增有序排列(以下称之为"逆序")时,总的比较次数达最大值(n+2)(n-1)/2(i>1),记录移动的次数也达最大 值(n+4)(n-1)/2(i>1);若待排序记录是随机的,即待排序列中的记录可能出现的各种排列的概率相同,则我们可取上述最小值和最大值的平均值,作为直接插入排序时所需进行关键字间的比较次数和移动记录的次数,约为n/4。由此,直接插入排序的时间复杂度为O(n2)。
ps:这里比较的时候切记要和哨兵进行比较所以最大次数为(n+2)(n-1)/2,首先假设第1一个有序,从第二个开始考虑才开始跟前面比,而为了避免向前越界,0下标跟要插入的值相等(更重要的是其他的用途),阻止了向前,实际上每个插入的值如果比所有已插入的值小的话还会跟0(哨兵)比较。非递减就是有重复的递增,因为递增是没有重复值的
直接插入排序的特点:算法简洁,容易实现,稳定
直接插入排序之PHP代码实现:
/**
* 插入排序
* 在要排序的一组数中,假设前面的数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。
*/
function insert_sort($arr){
$count = count($arr);
//假设第一个有序从第二个开始
for($i = 1;$i < $count;$i++){
$temp = $arr[$i]; //设置哨兵
$j=$i-1;
while($j>=0&&$temp<$arr[$j]){
$arr[$j+1]=$arr[$j];
$j--;
}
$arr[$j+1]=$temp;
}
}
以上就是关于插入排序之直接插入排序的一些介绍了,因为我主要是做PHP的所以算法只写了一个PHP的实现,后续会补上关于JS、python和Golang的实现。
希望此次分享能帮助到有需要的人。
所谓勇者,是心有所惧,唯自知尔!