二分查找

一、查找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值的最小下标还是最大下标分别有两种方法

3、对于找到刚好比key值小还是比key值大的就是在区间上增加一些判断条件即可，也就是上面的第二类题的第第二种解法

• 本文已收录于以下专栏：

举报原因： 您举报文章：二分查找 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)