前言 - 折半查找
近日在学习排序算法,在学到这般插入排序时再折半插入这里遇见了一些问题,遂分析一下这里的折半算法
过去折半一直是用于查找,也就是最终的条件是 ==
而这里的插入最终的条件是 > or <
这就是问题所在
我们先看看折半查找
//array 是数组
//num 是数组大小
//value 是待查找数
//返回值是带查找数在数组中的索引(-1即表示数组中没有这个数)
int binaryFind( int* array , int num , int value )
{
int low=0 , high=num-1;
while( low <= high )
{
if( value == array[(low+high)/2] )
return (low+high)/2;
else
if( value > array[(low+high)/2] )
low=(low+high)/2+1;
else
high=(low+high)/2-1;
}
return -1;
}
我们来分析一下 code 8行 里的判断条件为什么是 low<=high
很显然,如果判断条件是 == 时,若最后的情况是 low==high && array[(high+low)/2] == value ,即使数组中存在这个 value ,while 循环依然会终止,函数会返回 -1。
所以, <= 的作用是避免这种情况的发生。
折半插入排序
前言中已经写到,折半插入与折半查找的最大区别就是判断条件的不同,在折半查找中,每一次循环都会有 array[(high+low)/2] == value 的判断,显然折半插入是不能这样做的。
我们类比折半查找的 code 来写折半插入排序
-
code 8行中的判断条件 <= 要保留,前文折半查找不一定要循环到 high==low,而折半插入是一定要进行到这一步的。但是high==low 之后呢?如果判断条件是 < 那么我们所求的 index 在 high 的前面还是 high 的后面?我们举个例子
当 判断条件是 < 时:
array = {1,3,5,9,11} value=4 -> 最终 high=l=ow==1 , index 在 high 之后
array={1,3,5,9,11} value=8 -> 最终 high==low== 4 , index 即为 high
很显然这样不可行
如果判断条件是 <=:
我们知道,这种情况下最后一次循环之前 high==low ,之后进入循环
如果 index 在 high 之前 即 value < array[(low+high)/2]
high=(high+low)/2-1 -> 最终 high=index-1 , low=index
如果 index 在 high 之后 即 value > array[(low+high)/2]
low=(high+low)/2+1 -> 最终 high=index-1 , low=index
很显然,我们只需要返回 index 就可以了
-
code 10行 - 12行 删去
-
code 18行 返回low
代码
int binarytest( int *array , int num , int temp )
{
int low=0 , high=num-1;
while( low<=high )
{
if( temp > array[(high+low)/2] )
low=(high+low)/2+1;
else
high=(low+high)/2-1;
}
return low;
}