一、查找key元素所在的下标
//1、查找key所在位置的下标
int BinarySearch(int arr[], int len,int key)//[left,right]
{
if (arr == NULL || len <= 0)
return -1;
int left = 0;
int right = len - 1;
while (left <= right)
{
int mid = left +(right-left)/2;
if (arr[mid] == key)
{
return mid;
}
else if (arr[mid]<key)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
return -1;
}
二、查找key的值第一次出现的下标
1、方法一:
int BinarySearch_First1(int arr[], int len, int key)//[left,right]
{
if (arr == NULL || len <= 0)
return -1;
int left = 0;
int right = len - 1;
int res = -1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == key)
{
res = mid;
right = mid - 1;
}
else if (arr[mid] < key)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
return res;
}
2、方法二:
int BinarySearch_First2(int arr[], int len, int key)//[left,right]
{
if (arr == NULL || len <= 0)
return -1;
int left = 0;
int right = len - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == key)
{
if (mid >= 1 && arr[mid - 1] == key)
{
right = mid - 1;
}
else
{
return mid;
}
}
else if (arr[mid] < key)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
return -1;
}
三、查找key的值最后一次出现的下标
1、方法一:
int BinarySearch_Last1(int arr[], int len, int key)//[left,right]
{
if (arr == NULL || len <= 0)
return -1;
int left = 0;
int right = len - 1;
int res = -1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == key)
{
res = mid;
left = mid + 1;
}
else if (arr[mid] < key)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
return res;
}
2、方法二:
int BinarySearch_Last2(int arr[], int len, int key)//[left,right]
{
if (arr == NULL || len <= 0)
return -1;
int left = 0;
int right = len - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == key)
{
if (mid <= right - 1 && arr[mid + 1] == key)
{
left = mid + 1;
}
else
{
return mid;
}
}
else if (arr[mid] < key)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
return -1;
}
四、查找刚好小于key值的最大元素的下标
int BinarySearch_Small(int arr[], int len, int key)//[left,right]
{
if (arr == NULL || len <= 0)
return -1;
int left = 0;
int right = len - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == key)
{
right = mid - 1;
}
else if (arr[mid] < key)
{
if (mid <= right - 1 && arr[mid + 1] < key)
{
left = mid + 1;
}
else
{
return mid;
}
}
else
{
right = mid - 1;
}
}
return -1;
}
五、查找刚好小于key值的最小元素的下标
int BinarySearch_Big(int arr[], int len, int key)//[left,right]
{
if (arr == NULL || len <= 0)
return -1;
int left = 0;
int right = len - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == key)
{
left = mid - 1;
}
else if (arr[mid] < key)
{
left = mid + 1;
}
else if (arr[mid]>key)
{
if (mid >= 1 && arr[mid - 1] > key)
{
right = mid - 1;
}
else
{
return mid;
}
}
}
return -1;
}
六、总结
1、二分查找一定要关注区间是[ ]还是[ )
2、对应找到key值的最小下标还是最大下标分别有两种方法
但是方法一:适用于几个相等的值不连续的情况(例如;在有序但是含有N ULL的字符串数组中查找字符串)
3、对于找到刚好比key值小还是比key值大的就是在区间上增加一些判断条件即可,也就是上面的第二类题的第第二种解法