原始的二分查找非常简单,只要找到值返回即可;但是如果某值在数组中是重复的,比如 1 3 5 5 5 5 10 11 20这样,要求找到第一个5和最后一个5,就需要对原始的二分查找进行一点变形。
代码如下:
非递归版
int GetFirst_NonRecurse(int a[], int N, int k, int start, int end)
{
int mid;
while (start <= end)
{
mid = start + (end-start)/2;
if (a[mid] == k)
{
if (mid>0&&a[mid-1]!=k || mid==0)
return mid;
else
end = mid - 1;
}
else if (a[mid] > k)
end = mid - 1;
else
start = mid + 1;
}
return -1;
}
int GetLast_NonRecurse(int a[], int N, int k, int start, int end)
{
int mid;
while (start <= end)
{
mid = start + (end - start)/2;
if (a[mid] == k)
{
if (mid < N-1 && a[mid+1] != k || mid == N-1)
return mid;
else
start = mid + 1;
}
else if (a[mid] > k)
{
start = mid + 1 ;
}
else
{
end = mid - 1;
}
}
return -1;
}
递归版
int GetFirst(int a[], int N, int k, int start, int end)
{
if (start > end)
return -1;
int mid = start + (end-start)/2;
if (a[mid] == k)
{
if (mid>0&&a[mid-1]!=k || mid==0)
return mid;
else
end = mid - 1;
}
else if (a[mid] > k)
end = mid - 1;
else
start = mid + 1;
return GetFirst(a,N,k,start,end);
}
int GetLast(int a[], int N, int k, int start, int end)
{
if (start > end)
return -1;
int mid = start + (end - start)/2;
if (a[mid] == k)
{
if (mid k)
{
end = mid - 1;
}
else
{
start = mid + 1;
}
return GetLast(a,N,k,start,end);
}