A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© simonqian 中级黑马   /  2013-5-9 11:02  /  2800 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 simonqian 于 2013-5-9 21:27 编辑

public static int Search(int[] array,int value)
        {
                int min = 0;
                int max = array.length-1;
                int middle;
               
                while(min <= max)
                {
                        middle = (max+min)/2;
                        //为什么这么写                        
                                                  if(value < array[middle])
                        {
                                max=middle-1;
                        }
                        //为什么这么写
                        if(value > array[middle])
                        {
                                min =middle+1;
                        }
                                                   //为什么这么写
                        if(array[middle] == value)
                        {
                                return middle;
                        }
                }
                return -1;
               
        }

评分

参与人数 1技术分 +1 收起 理由
曹睿翔 + 1 新人鼓励

查看全部评分

8 个回复

倒序浏览
每次砍半,只有和中间数比较才知道要找的数在哪一半,如果你找的数在这一半,就把另外一半舍弃,继续砍半查找,如此循环
回复 使用道具 举报
二分法查询思想的前提是:数据是有序的(升序或降序),
如升序:2,3,5,7,30(降序:10,8,6,4,1);
然后将需要查找的数据和数组中长度一半的位置开始比较:
如果相等,则找到目标数据;
如果目标数据小于array[middle],则在数组的前一半中继续查找,这时最大角标为 max=middle-1;
否则就只数组的后一半中继续查找,这时最小的角标为min =middle+1;
这样进行下去直到找到目标数据,如果查找不到,说明数据不存在;
这种算法进行一次查找就能省去一半的数据比较,查找效率较高;
      
小例子:
    如果你要在arr={2,4,32,35,45,52,54}中查找4:
    a 首先拿4和这个数组中的最中间的数据arr[3]=35进行比较,
      由于4<35,所以第二次比较的时候只需要和arr[3]之前的数据进行比较就行,
      因为arr[3]之后的数肯定大于4,4肯定不是在arr [3]之后;
    b 第二次就在arr[0]和arr[2]之间查找4;
       因为arr[1]=4,这样就找到目标数据了;
   

评分

参与人数 1技术分 +1 收起 理由
曹睿翔 + 1 赞一个!

查看全部评分

回复 使用道具 举报
数据是有序的,每次把数据分成两部分,取中间数值为比较点,拿你要比较的数据和他比大小,然后去相对的区域再次查找比较,这样可以每次缩减一半要比较的区域
回复 使用道具 举报
我用个例子说一下吧,比如我有一个数组,是1~100之间的,然后要找一个数,78。然后二分法的思路是这样的,先找1~100之间数的一半,就是50五十就是1 100除以2,就是min max除以2,50比value要小,说明value比50大,就是在51到100之间,因为刚好50找过了,然后再找51到100之间的,这样一直循环,假如数组中有这个数就肯定可以找到。假如数组中没有这个数,比如说是25.3,当但是数组中没有,当折半到最大值为26,最小值为24的下一次,就是中间值为25,但是25并不是要找的数,于是26就变成min于是它们再折中,就是26 26除以2,还是26,26比25.3大,于是max就变为26-1就是25但是min确实26,这样就会min大于max,但是这明显不符合逻辑啦,也就是说数组中没有要找的数学,爪机无力,只能说一下我的一个思路,希望能帮到你

评分

参与人数 1黑马币 +6 收起 理由
曹睿翔 + 6 神马都是浮云

查看全部评分

回复 使用道具 举报
折半查找 首先要设三个变量(a,b,c),分别保存数组元素的开始、中间和末尾的序号。假设有10个元素,a=0,c=9,b=(a+c)/2=4,接着进行判断:
1.如果序号位b的元素的值与x相等,说明查找到了数据 ,返回序号c
2.如果x小于c角标所在的值,说明要查找的x位于a和b角标之间,b和c之间的元素将不再查找。因此将c的值改为b-1,然后重新查找a与c之间的数据
3.若x大于b角标的值,则要查找的数据位于b和c之间,a和b之间的元素将不再查找。这时a的值改变为b-1,程序重新查找a到c之间的数据
4.如果循环到a>c时还未找到目标数据,则表示此数组中不存在该元素

评分

参与人数 1技术分 +1 收起 理由
曹睿翔 + 1 你设置个头像技术分还会加1

查看全部评分

回复 使用道具 举报
你好。我在代码上回答了你的问题。你仔细看看:
public static int Search(int[] array,int value)
{
                int min = 0;
                int max = array.length-1;
                int middle;
          
                while(min <= max)
                {
                                middle = (max+min)/2;
                                //为什么这么写
                                //这就是二分查找的核心了。定义一个中间值代表中央角标。最大角标max加最小角标min。再除以2.这就是中间的角标了。而且在循环里面。意思就是每次循环到这都要折半
                                if(value < array[middle])
                                {
                                                max=middle-1;
                                }
                                //为什么这么写
                                //假如value是50(要找的数),而array[middle](中间角标)的值是60.那么是不是应该最大角标到中间角标的坐标去啊。因为60的后面不能有小于50 的数。
                                if(value > array[middle])
                                {
                                                min =middle+1;
                                }
                                //为什么这么写
                                //这个道理就简单了。假如中间角标值是30,要找的数是50 ,那么是不是要把最小角标移到中间角标的右边一位去啊。。因为中间角标值得左边就不可能有小于50的数。
                                if(array[middle] == value)
                                {
                                                return middle;
                                }
                }
                return -1;
                //其实我感觉你不是代码不会写。而是不理解角标的走向。你可以通过画图来理解的。意思理解了就只要在代码上实现了
          
}
回复 使用道具 举报
黑马-雷钊 发表于 2013-5-9 18:57
你好。我在代码上回答了你的问题。你仔细看看:
public static int Search(int[] array,int value)
{

谢谢,看懂了
回复 使用道具 举报
xiaohu1218 发表于 2013-5-9 13:31
二分法查询思想的前提是:数据是有序的(升序或降序),
如升序:2,3,5,7,30(降序:10,8,6,4,1) ...

讲的很细,学习了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马