折半查找插入排序

本文将结合 二分查找直接插入排序 的知识点,介绍折半查找插入排序

你可以通过点击以往文章回顾知识点:

点击 -> 二分查找

点击 -> 直接插入排序

算法思想

在维护一个有序序列的过程中,从左往右看,使用二分查找出第一个比 base 大的数的位置 l,然后将元素后移,在 l 处腾出空间,将 base 插入。

一个简单的例子:

image-20230122232426185

算法模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void binary_insert_sort(){
// 维护一个有序序列
for(int i = 1 ; i < n ; i++){
// 相邻元素顺序情况
if(q[i - 1] <= q[i]) continue;
// 相邻元素逆序情况
// 二分,从左往右找到第一个大于 base 的数
int l = 0, r = i, base = q[i];
while(l < r){
int mid = l + r >> 1;
if(q[mid] > base) r = mid;
else l = mid + 1;
}
// 将 l 空出来
for(int j = i - 1 ; j >= l ; j--)
q[j + 1] = q[j]; // 元素后移,空出 l 这个位置
// 插入
q[l] = base;
}
}

折半查找插入排序 VS 直接插入排序

时间复杂度

  • 最好情况:O(n)
  • 平均情况:理论上来说,折半查找插入排序是比直接插入排序要快的,毕竟是直接插入排序的优化版本。折半查找插入排序通过二分来优化比较次数,时间复杂度是O(nlogn),但是移动次数并没有优化,因此时间复杂度还是O(n2)与直接插入排序一样。
  • 最坏情况:O(n2)

空间复杂度:O(1)(都是常数额外辅助空间)

稳定性:稳定(相同大小元素不改变相对位置)

技术支持

我自己