(一) 算法描述
折半插入排序是直接插入排序的一种优化,在直接插入排序中待排序的元素需要与有序数列的每个元素从后往前逐个进行比较,直接插入排序对基本有序数列具有很高的排序效率,但是当乱序情况下,其比较次数会很多。折半插入排序在直接排序的基础上在位置查找部分采用折半(二分查找)算法进行插入位置的确定,进而节省查找时间。
(二) 算法分析
- 最差时间复杂度:\(O(n^2)\)
- 最好时间复杂度:\(O(nlogn)\)
- 平均时间复杂度:\(O(n^2)\)
- 空间复杂度: \(O(1)\)
- 稳定性: 稳定
(三) 算法伪码
1 | INSERTION-SORT(A) |
(四) 算法步骤
- 缓存当前要排序的元素的值,以便找到正确的位置进行插入;
- 计算 0 ~ i-1 的中间点,用 i 索引处的元素与中间值进行比较,如果 i 索引处的元素大,说明要插入的这个元素应该在中间值和刚加入i索引之间,反之,就是在刚开始的位置 到中间值的位置,这样很简单的完成了折半;
- 在相应的半个范围里面找插入的位置时,不断的用(1)步骤缩小范围,不停的折半,范围依次缩小为 1/2 1/4 1/8 …….快速的确定出第i个元素要插在什么地方;
- 确定位置之后,将整个序列后移,并将元素插入到相应位置。
(五) java实现
1 | /** |
(六) python实现
1 | class InsertSort(object): |
(七) 算法优缺点
1. 优点
相对于直接插入排序比较次数少,查找速度快,平均性能好;
2. 缺点
要求待查表为有序表;
插入删除困难:因为折半查找法要求待查表为有序表,所以在插入的时候你就不能随便插入了。你必须找到待插入的元素在表中的位置才可以插入,所以插入的时候比较麻烦。
(八) 总结
当n较大时,二分插入排序的比较次数比直接插入排序的最差情况好得多,但比直接插入排序的最好情况要差,所当以元素初始序列已经接近升序时,直接插入排序比二分插入排序比较次数少。二分插入排序元素移动次数与直接插入排序相同,依赖于元素初始序列。
如果比较操作的代价比交换操作大的话可以采用二分插入排序。
参考博客