最近在准备找实习,参加阿里的校招笔试时遇到了二分法的改错题,以前总是死记硬背,现在,呵呵,还是理解了比较好。
int B_SearchEqual(int* A, int n, int _value)
{
int low = 0;
int high = n - 1;
while(low <= high)
{
int mid = low + ((high - low)>>1);
if(A[mid] > _value)
high = mid - 1;
else if(A[mid] < _value)
low = mid + 1;
else
return mid;
}
return -1;
}
同学在看STL源码剖析时遇到二分法的一些变形:大于_value 的第一个数字的位置,没有则返回-1;小于_value的最后一个数字的位置,没有则返回-1;
第一个_value的位置; 最后一个_value的位置;
1、首先,大于_value 的第一个数字的位置,没有则返回-1:
int B_SearchFirstGreater(int* A, int n, int _value)
{
int low = 0;
int high = n - 1;
while(low <= high)
{
int mid = low + ((high - low)>>1);
if(A[mid] > value)
high = mid - 1;
else
low = mid + 1;
}
if(A[low] > ta)
return low;
else
return -1;
}
2、小于_value的最后一个数字的位置,没有则返回-1
int B_SearchLastSmaller(int* A, int n, int _value)
{
int low = 0;
int high = n - 1;
while(low <= high)
{
int mid = low + ((high - low)>>1);
if(A[mid] >= _value)
high = mid - 1;
else
low = mid + 1;
}
if(A[high] > ta)
return high;
else
return -1;
}
int B_SearchFirstEqual(int* A, int n, int _value)
{
int low = 0;
int high = n - 1;
while(low <= high)
{
int mid = low + ((high - low)>>1);
if(A[mid] >= _value)
high = mid - 1;
else
low = mid + 1;
}
if(A[low] == _value)
return low;
else
return -1;
}
4、最后一个_value的位置
int B_SearchLastEqual(int* A, int n, int _value)
{
int low = 0;
int high = n - 1;
while(low <= high)
{
int mid = low + ((high - low)>>1);
if(A[mid] > _value)
high = mid - 1;
else
low = mid + 1;
}
if(A[high] == _value)
return high;
else
return -1;
}
虽然实现方法不同,但是原理是一样的,so在此补充一些延伸的题目:
5、_value在有序表中出现的个数
int CalEqualCounts(int* A, int n, int _value)
{
int first_index = B_SearchLastSmaller(A, n, _value) + 1;
if(first_index == -1)
return 0;
int last_index = B_SearchFirstGreater(A, n, _value) - 1;
return last_index - first_index + 1;
}