今天看了博客园的一篇 "只有10%程序员能正确实现二分查找算法" 一开始有点不服气,我想啊,二分查找啊,这也太简单了吧.然后自己动手用C#写了一个,测试正常数据,哇,第一次就成功,不错,代码如下:
代码
/// <summary>
/// 二分查找算法
/// </summary>
/// <param name="t">数组</param>
/// <param name="num">要查找的数字</param>
/// <param name="begin">开始索引</param>
/// <param name="end">结束索引</param>
/// <returns>数字在数组中的索引,不存在返回-1</returns>
static int BSearch(int[] t, int num, int begin, int end)
{
int mid = 0;
for (;; )
{
if (begin>end) return -1;
mid = (begin + end) / 2;
if (t[mid] == num)
{
return mid;
}
else if (t[mid] > num)
{
end =mid;
}
else
{
begin =mid;
}
}
}
/// 二分查找算法
/// </summary>
/// <param name="t">数组</param>
/// <param name="num">要查找的数字</param>
/// <param name="begin">开始索引</param>
/// <param name="end">结束索引</param>
/// <returns>数字在数组中的索引,不存在返回-1</returns>
static int BSearch(int[] t, int num, int begin, int end)
{
int mid = 0;
for (;; )
{
if (begin>end) return -1;
mid = (begin + end) / 2;
if (t[mid] == num)
{
return mid;
}
else if (t[mid] > num)
{
end =mid;
}
else
{
begin =mid;
}
}
}
可是真的正确吗?答案是否定的,比如:原来t数组的值为 t={0,1,2,3,4,5,6,7,8,9,10},我现在调用它BSearch(t,4,0,4) 按理说应该返回 4呀.我编译运行.怎么屏幕半天也没反应呀.嗯.对.程序出现死循环了!!!.为什么呢,通过我仔细分析了以上代码.
mid=(0+4)/2 begin=2;end=4
mid=(2+4)/2 begin=3;end=4
mid=(3+4)/2 begin=3;end=4
......
果然出现死循环了.在仔细整了一遍思路.原来是我边界没处理好.也就是说.如果发现num>t[mid]的时候,即所查找的数可能在数组的后半部分.这时候的begin=mid就错了,因为t[mid]已经比较过,所以这个时候begin应该为mid+1,同理,num<t[mid]的时候,end=mid-1.
修改后的正确代码:
代码
/// <summary>
/// 二分查找算法
/// </summary>
/// <param name="t">数组</param>
/// <param name="num">要查找的数字</param>
/// <param name="begin">开始索引</param>
/// <param name="end">结束索引</param>
/// <returns>数字在数组中的索引,不存在返回-1</returns>
static int BSearch(int[] t, int num, int begin, int end)
{
int mid = 0;
for (;; )
{
if (begin>end) return -1;
mid = (begin + end) / 2;
if (t[mid] == num)
{
return mid;
}
else if (t[mid] > num)
{
end =mid-1;
}
else
{
begin =mid+1;
}
}
}
/// 二分查找算法
/// </summary>
/// <param name="t">数组</param>
/// <param name="num">要查找的数字</param>
/// <param name="begin">开始索引</param>
/// <param name="end">结束索引</param>
/// <returns>数字在数组中的索引,不存在返回-1</returns>
static int BSearch(int[] t, int num, int begin, int end)
{
int mid = 0;
for (;; )
{
if (begin>end) return -1;
mid = (begin + end) / 2;
if (t[mid] == num)
{
return mid;
}
else if (t[mid] > num)
{
end =mid-1;
}
else
{
begin =mid+1;
}
}
}
汗,二分查找果然不简单,终于整出正确的二分查找标准代码了.当然以上代码还可以进行加速的.也就是如以上的if经常要判断两次.那么如何才能让它减少到只要判断一次呢?感兴趣的朋友可以去看看<<编程珠玑>>这本书,我记得这本书里面有写到过实现方法.具体怎么实现.大家也想想^_^