在有序数组中通过二分法查找数字
在一个从左到右递增的有序数组中,通过二分法查找数字
#include <iostream>
using namespace std;
int dichotomy(int* pArr, int len, int val)
{
// 左索引
int left = 0;
// 右索引
int right = len-1;
// 中间二分索引
int middle = 0;
while( left <= right )
{
middle = left + (right - left)/2; // 可以写成 (left + right)/2
// 在左边
if( pArr[middle] > val )
{
right = middle - 1;
}
// 在右边
else if( pArr[middle] < val )
{
left = middle + 1;
}
// 找到了
else
{
return middle;
}
}
return -1;
}
int main(void)
{
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
cout << dichotomy(arr, sizeof(arr)/sizeof(arr[0]), 4) << endl;
return 0;
}
在有序数组中通过二分法查找某个数字最左边的位置
在一个从左到右递增的有序数组中,通过二分法查找,找到>=num的最左边的值
#include <iostream>
using namespace std;
int dichotomyLeft(int* pArr, int len, int val)
{
// 左索引
int left = 0;
// 右索引
int right = len-1;
// 中间二分索引
int middle = 0;
while( left <= right )
{
middle = left + (right - left)/2; // 可以写成 (left + right)/2
// 在左边
if( pArr[middle] > val )
{
right = middle - 1;
}
// 在右边
else if( pArr[middle] < val )
{
left = middle + 1;
}
// 找到对应值
else
{
// 当对应值左边等于自己时,说明还不是对应值最左边的数字,此时继续向左二分
if( pArr[middle-1] == pArr[middle] )
{
right = middle - 1;
}
else
{
return middle;
}
}
}
return -1;
}
int main(void)
{
int arr[] = {1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6};
cout << dichotomyLeft(arr, sizeof(arr)/sizeof(arr[0]), 4) << endl;
return 0;
}
在无序数组中找到一个局部最小值
在一个无序数组中,通过二分查找找到一个局部的最小值
#include <iostream>
using namespace std;
int localMinimumVal(int* pArr, int len)
{
// 先判断左右两边,如果左右两边出现局部最小,直接返回
if( pArr[0] < pArr[1] )
{
return 0;
}
if( pArr[len-1] < pArr[len-2] )
{
return len-1;
}
// 左右不是局部最小,左边的趋势-> \ / <-右边的趋势
// 可以看出中间时洼地,向中间找即可
// 左索引
int left = 1;
// 右索引
int right = len-2;
// 中间二分索引
int mid = 0;
int index = 0;
while( left <= right )
{
mid = left + (right - left)/2; // 可以写成 (left + right)/2
// mid直接就是洼地
if( (pArr[mid] < pArr[mid-1]) && (pArr[mid] < pArr[mid+1]) )
{
return mid;
}
// 如果只小于左边,就看右边
else if( pArr[mid] < pArr[mid-1] )
{
left = mid + 1;
}
// 如果只小于右边,就看左边
else if( pArr[mid] < pArr[mid+1] )
{
right = mid - 1;
}
// 如果中间是极大值,就在递归左右
else
{
// 递归左边
index = localMinimumVal(pArr, mid+1);
if( index != -1 )
{
return index;
}
// 递归右边
index = localMinimumVal(pArr+mid, len-mid);
if( index != -1 )
{
return mid+index;
}
else
{
return -1;
}
}
}
return -1;
}
int main(void)
{
int arr[] = {8, 7, 9, 8, 8, 7, 9, 9, 9, 8, 8, 8, 9, 7, 8};
cout << localMinimumVal(arr, sizeof(arr)/sizeof(arr[0])) << endl;
return 0;
}