码迷,mamicode.com
首页 > 编程语言 > 详细

算法实现回顾1——二分查找

时间:2014-12-28 14:11:46      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:

前话:

为什么写这个系列?
算法的精髓除了在于算法的一个设计,更在于算法的一个好的设计。前者可能需求一个好的算法工程师,而后者则需求一个优秀的程序员。
很多时候我们往往只希望去了解一种设计思路,但是对于程序员,一种优良的实现是非常重要的。
实现的细节才决定成败。毕竟程序员面对和输出的都是程序,而不是思路。

引用:

你真的会二分查找吗?http://blog.csdn.net/int64ago/article/details/7425727
二分查找,你真的会吗?http://www.ahathinking.com/archives/179.html
你真的会写二分检索吗?http://blog.chinaunix.net/uid-1844931-id-3337784.html

正文

要说实现,必须从思路开始,一个开始位置start和一个结束位置end。
好的,
问题一来了,我们知道循环结束是start要超过end,那么等号怎么办?
TestCase1:1个数,我们允许循环时没等号,例如:
while(start<end){}
一个数的话直接不查了。OK,=必须是要的。
好,继续,start<=end时我们要做什么呢?二分法,当然是mid取中啦。
mid=(start+end)/2 or >>1 其实编译器会优化的,你以为人家傻?人家尾递归都会。
然后比较 mid位置的值和要求的值的,然后替换start或end,这时候问题又来了,
问题二:怎么替换,或者说用哪个值替换?
我们想,如果中间数大,说明值要在前半部分,end必须改掉,ok,改成mid?
这里是个错,如果start和end间隔,mid是start,用start替换可能会造成死循环。。over
所以end替换的时候用mid-1,start替换的时候mid+1
问题三,等号需要处理吗?
通常是要先判断是不是和中间值相等的,等号就直接返回了,这是很正常的逻辑。
而上边第一个链接,里边是没有=的。
我们这样想,如果发生了相等,但我们没直接返回,而继续寻找,直到start=end=(pos-1 or pos+1)。
按链接1中YES_LEFT方法:原数组 1 2 5,找2.
s=0 e=2 m=1 *mid>=val e=mid-1
s=0 e=0 mid=0 *mid<val s=mid+1 return s=1
找3 s=0 e=2 m=1 *mid<val s=mid+1
s=2 e=2 mid=2 *mid>=val e=mid-1 return s=2
此方法的特点是mid和val比较是>=,返回的是start
说明返回的是不小于val的最小值的位置
YES_RIGHT找2.s=0 e=2 m=1 *mid<=val s=mid+1
s=2 e=2 mid=2 *mid>val e=mid-1 return e=1
若找3 s=0 e=2 m=1 *mid<=val s=mid+1
s=2 e=2 mid=2 *mid>val e=mid-1 return e=1
此方法的特点是mid和val比较是>,返回的是end
说明返回的是不大于val的最大值的位置
跳出时必然s>e准确的说s=e+1,当val值未找到时,s是比val大的,e是比val小的
注意的是下边这种可能会返回-1
很多时候我们要找到不大于val数的个数,这是我们选择下边这种+1即可
问题四,进一步处理一些特殊情况.
特殊情况包括,找的正好是首末位。这种情况就是在循环前作判断。
循环内加等号判断也可以加快找到后退出。
OK,现在看下正常的实现

int bSearch(int data[],int len,int val)
{
   if(*data==val)return 0;
   if(*data+len-1==val)return len-1;
   int s=0,e=len-1,mid=0;
   while(s<=e)
   {
      mid=(s+e)/2;
      if(*data+mid==val)return mid;
      if(*data+mid>val)e=mid-1;
      else s=mid+1;
   } 
   return e;      
}

 

算法实现回顾1——二分查找

标签:

原文地址:http://www.cnblogs.com/Cnil/p/4189862.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!