活动地址:CSDN21天学习挑战赛
今天的内容首先是一个排序算法,二分插入排序算法也叫这般插入排序。也即是直接插入排序的优化算法。
二分插入排序算法
这个排序算法实际就是将两个算法融合起来,在直接插入排序的过程中会产生一个有序区间,每次我们需要在这个有序区间内查找一个位置,就是下一个数字该处在哪一个位置边查找边移动元素,实际的比较次数会比较多,在元素量比较大的时候,但是看到有序区间,是不是该想到什么算法?二分,在有序区间内搜索插入位置,当然使用二分算法了。这样可以优化查找的复杂度从N到logN,但是实际算法的复杂度并没有改变,因为要移动元素所以整体排序复杂度还是O(N^2).
但是这个例子是为了说明算法之间是可以融合形成新的算法的,这种思路需要了解,就是在某个算法的内部存在某些可以使用其他算法进行优化的部分。
下面来看一下二分插入排序算法的代码实现(C语言)
//排升序,找到大于等于target的第一个元素的下标返回
int bin_find(int* arr, int l, int r,int target)
{
while (l < r)
{
int mid = l + r >> 1;
if (arr[mid] > target)
r = mid;
else
l = mid + 1;
}
return l;
}
void Insert_sort_bin(int* arr, int size)
{
for (int i = 1; i < size; i++)
{
if (arr[i] < arr[i - 1])
{
int tmp = arr[i];
int end = i - 1;
int pos = bin_find(arr, 0, end, tmp);
while (end >= pos)
{
arr[end + 1] = arr[end];
end--;
}
arr[pos] = tmp;
}
}
}
这里需要注意的一点就是,加了一个if判断,只有当arr[i] < arr[i - 1],才满足交换的条件,否则直接不需要移动arr[i]的位置,因为其本身就在正确的位置上。因此加上之后可以减少一些不必要的交换,并且在二分这里如果不加就是错误的,因为二分会查找一个位置,将pos位置的值向后移动然后插入新的值。