二分查找的应用场景:
二分查找目的是在一堆数中找到指定的数。
使用二分查找这些数据需要有的特征(面试容易问):
- 存储在数组中。
- 有序的排列。
如果是链表就无法使用二分查找。
顺序数组是递增递减,是否有重复的数据没有关系。
二分查找的实现
“分治法”,分治法基本都可以用递归来实现的,二分查找法的递归实现如下:
int SearchBin(int array[], int low, int high, int key)
{
if (low<=high)
{
int mid = (low+high)/2; //而是用 mid=low+((high-low)/2),原因是
//使用(low+high)/2会有整数溢出的问题
if(key == Array[mid])
return mid;
else if(key<Array[mid])
return BinSearch(Array,low,mid-1,key); //移动low和high
else if(key>Array[mid])
return BinSearch(Array,mid+1,high,key); //移动low和high
}
else
return -1;
}
非递归的方法实现二分查找:
/*
* 非递归二分查找算法
* 参数:整型数组,需要查找的数.
*/
int SearchBin(int *srcArray,int nSize,int key)
{
if ( srcArray== NULL || nSize == 0 )
return -1;
int low = 0;
int high = nSize - 1;
int mid = 0;
while ( low <= high )
{
mid = (low + high )/2;
if ( array[mid] < key)
low = mid + 1;
else if ( array[mid] > key )
high = mid - 1;
else
return mid;
}
return -1;
}
项目中实际使用的例子:
BOOL SearchBin(CASocket * pTarget,DWORD & dwPos) //二分查找算法
{
dwPos = (DWORD)-1;
DWORD low,mid,high;
BOOL bResult = FALSE;
low = 1; high = m_nEventCount; //初始化查找区间
while ( low <= high )
{
if((int)high<0)
{
dwPos = 0;
return FALSE;
}
mid = ( low + high )/2 ; //求区间中心的位置
if ( m_ASocketObject[mid] == pTarget )
{
bResult = TRUE;
dwPos = mid;
break;
}
if ( m_ASocketObject[mid] > pTarget )
high = mid - 1 ;//中心节点关键字偏大,查找低半段
else
low = mid + 1 ; //中心节点关键字偏小,查找高半段
}
if(dwPos == (DWORD)-1)
{
dwPos = (low + high)/2+1;
}
return bResult; //查找失败,返回失败标志
}