一、题目大意
在数组中查找元素val,找到了返回下标,没找到返回-1
二、具体实现
如果在该数组中查找数字110的下标
1、1.0版(有错误)
(1)错误1:没有特殊情况判断。应该加上if(NULL == br || n<1 ) return-1;
(2)错误2: while (left < right) 错误,只有一个元素的时候就没有进行查询,left == right时候还有一个元素没有查询
(3)错误3:int mid = (right + left) / 2;会发生越界行为。例如第二趟查找的时候,l+r = 18 > 数组长度
(4)错误4:int mid = (right - left + 1) / 2; 在第二趟的时候,如果使用该方法,那么m = 3。还在第一趟数据,所以还得加上一个left.
int FindValue(const int* br, int n, int val)
{
//错误1
int left = 0, right = n - 1;
while (left < right) //错误2
{
int mid = (right + left) / 2;//错误3
int mid = (right - left + 1) / 2; //错误4
int mid = (right - left + 1) / 2 + left;
if (val < br[mid])
{
right = mid - 1;
}
else if (val > br[mid])
{
left = mid + 1;
}
else
{
return mid;
}
}
return -1;
}
2、2.0版本有重复值问题
int ar[] = { 12,12,12,12,12,12,12,23,33,45,56,78,90 };
返回最左边的值,例如0
返回最右边的值,例如6,只需将代码改为while (mid < right && br[mid + 1] == val){++ mid}
int FindValue(const int* br, int n, int val)
{
int pos = -1;
int left = 0, right = n - 1;
if(NULL == br || n<1 )return pos;
while (left <= right)
{
int mid = (right - left + 1) / 2 + left;
if (val < br[mid])
{
right = mid - 1;
}
else if (val > br[mid])
{
left = mid + 1;
}
else
{
while (mid > left && br[mid - 1] == val)
{
--mid;
}
pos = mid;
break;//假设找到了,left和right不会改变了,while就一直是ture。如果没有break,循环无法退出
}
}
return pos;
}
3、3.0版本改为递归 要使用两个函数
int Find(const int* br, int left, int right, int val)
{
int pos = -1;
if (left <= right)
{
int mid = (right - left + 1) / 2 + left;
if (val < br[mid])
{
pos = Find(br, left, mid - 1, val);
}
else if (val > br[mid])
{
pos = Find(br, mid+1, right, val);
}
else
{
while (mid > left&& br[mid - 1] == val) --mid;
pos = mid;
}
}
return pos;
}
int FindValue(const int* br, int n, int val)
{
if (NULL == br || n < 1)return -1;
else return Find(br, 0, n - 1, val);
}
主函数
int main()
{
int ar[] = { 0,12,12,12,12,12,12,12,23,34,45,67,89,90 };
int n = sizeof(ar) / sizeof(ar[0]);
int val = 12;
int pos = FindValue(ar, n, val);
printf("%d\n", pos);
return 0;
}