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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 江大海 中级黑马   /  2013-4-19 07:57  /  2148 人查看  /  13 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

这个是我写的一个二分查找,编译通过,为什么会说是角标越界异常呢?我写了if (min>max)语句啊,和老师写的对比了半天也不知道为什么,求帮助
  1. /*二分查找
  2. */

  3. class ArrDemo_2
  4. {
  5.         public static void main(String[] args)
  6.         {
  7.                 int [] arr ={1,2,3,4,5,6};
  8.                 halfSearch(arr,31);
  9.                
  10.         }
  11.         public static void halfSearch(int [] arr,int key)
  12.         {
  13.                 int min = 0,max = arr.length,mid;
  14.                 mid = (min +max)/2;
  15.                 while (arr[mid]!=key)
  16.                 {
  17.                        
  18.                  if (arr[mid]>key)
  19.                         {
  20.                                 max = mid-1;
  21.                                 mid = (min +max)/2;
  22.                         }
  23.                         else if (arr[mid]<key)
  24.                         {
  25.                                 min = mid+1;
  26.                         mid = (min +max)/2;
  27.                         }
  28.                        
  29.                         if (min>max)
  30.                         mid=-1;
  31.                
  32.                        
  33.                 }
  34.                 System.out.println(mid);
  35.         }
  36. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

13 个回复

倒序浏览
14行:int min = 0,max = arr.length,mid;
min既然定义成0,与第一个元素对应,
那max应该为arr.length-1,下标为arr.length的元素不存在,当然会越界。

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
int min = 0,max = arr.length,mid;
你这里的max所取的值越界了,应该是max=arr.length-1,数组的长度是arr.length但是能取的下标却是arr.length-1,因为数组的下标是从零开始的。

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报

  1. //   整形数组长度是六
  2. 08.                int [] arr ={1,2,3,4,5,6};
  3. //   传31 就出问题了
  4. 09.                halfSearch(arr,31);
复制代码
java.lang.ArrayIndexOutOfBoundsException  : 这个异常是数组角标越界异常

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
int min = 0,max = arr.length,mid; //元素有arr.length个,但元素的坐标是0——arr.length-1
另外折半查找中我想问是:
mid = (min +max)/2;
  mid = (min +max)>>1;的速度快点?



评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 黑马伍哲沂 于 2013-4-19 09:08 编辑

这个代码里有三个问题:
第一,max应该是length-1;
第二,循环条件,应该要改,有两种该法,⑴改为while(min<max),如果这么改,则mid=(min+max)/2或者mid=(min+max)>>1只能在判断之前,即在循环内第一条语句。⑵改为while(min<=max),则后面的可以不改。
第三,第30行,if,用else即可。
我用两种方法修改后的程序如下供参考(注:我用的是带返回值的,返回角标更合理):
  1. public static int halfSearch(int [] arr,int key)
  2.         {
  3.                         int min = 0,max = arr.length-1,mid=(min+max)/2;
  4.                         while (min <= max)         
  5.                         {
  6. //                                mid = (min +max)/2;
  7.                                        
  8.                                 if (arr[mid]>key)
  9.                                 {
  10.                                         max = mid-1;
  11.                                         mid = (min +max)/2;
  12.                                 }
  13.                                 else if (arr[mid]<key)
  14.                                 {
  15.                                         min = mid+1;
  16.                                         mid = (min +max)/2;
  17.                                 }
  18.                                                 
  19.                                 else
  20.                                         return mid;
  21.                         }
  22.                         return -1;

  23.         }
复制代码
或者
  1. public static int halfSearch(int [] arr,int key)
  2.         {
  3.                         int min = 0,max = arr.length-1,mid=(min+max)/2;
  4.                         while (min < max)
  5.                         {
  6.                                 mid = (min +max)/2;
  7.                                        
  8.                                 if (arr[mid]>key)
  9.                                 {
  10.                                         max = mid-1;
  11.                                         //mid = (min +max)/2;
  12.                                 }
  13.                                 else if (arr[mid]<key)
  14.                                 {
  15.                                         min = mid+1;
  16.                                         //mid = (min +max)/2;
  17.                                 }
  18.                                                 
  19.                                 else
  20.                                         return mid;
  21.                         }
  22.                         return -1;

  23.         }
复制代码

评分

参与人数 1技术分 +2 收起 理由
陈丽莉 + 2

查看全部评分

回复 使用道具 举报
  1. int [] arr ={1,2,3,4,5,6};
  2. nt min = 0,max = arr.length,mid;
复制代码
错误在:max = arr.length,应该为,max = arr.length-1。
分析哈角标的移动:
C:\Documents and Settings\Administrator\桌面\1.JPG

1.JPG (66.79 KB, 下载次数: 12)

1.JPG

评分

参与人数 1技术分 +2 收起 理由
陈丽莉 + 2

查看全部评分

回复 使用道具 举报
  1. /*二分查找
  2. */

  3. class ArrDemo_2
  4. {
  5. public static void main(String[] args)
  6. {
  7. int [] arr ={1,2,3,4,5,6};
  8. halfSearch(arr,31);

  9. }
  10. public static void halfSearch(int [] arr,int key)
  11. {
  12. int min = 0,max = arr.length,mid;
  13. mid = (min +max)/2;
  14. while (arr[mid]!=key)
  15. {

  16. if (arr[mid]>key)
  17. {
  18. max = mid-1;
  19. mid = (min +max)/2;
  20. }
  21. else if (arr[mid]<key)
  22. {
  23. min = mid+1;
  24. mid = (min +max)/2;
  25. }

  26. if (min>max)
  27. mid=-1;


  28. }
  29. System.out.println(mid);
  30. }
  31. }
复制代码
报错的地方是十四行,你定义max的时候max的最大角标应该是arr。length-1.因为你传递的数组长度是6 而最大角标值是5

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
你的代码没有错


class ArrDemo_2

{

        public static void main(String[] args)

        {

                int [] arr ={1,2,3,4,5,6};

                halfSearch(arr,31);//是你在这里定义的31出了问题,是因为你定义  int [] arr ={1,2,3,4,5,6};没有31这个数,你可以传个3试试



               

        }

        public static void halfSearch(int [] arr,int key)

        {

                int min = 0,max = arr.length,mid;

                mid = (min +max)/2;

                while (arr[mid]!=key)

                {

                        

                 if (arr[mid]>key)

                        {

                                max = mid-1;

                                mid = (min +max)/2;

                        }

                        else if (arr[mid]<key)

                        {

                                min = mid+1;

                        mid = (min +max)/2;

                        }

                        

                        if (min>max)

                        mid=-1;

               

                        

                }

                System.out.println(mid);

        }

}

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
soga.知道了,谢谢啦
回复 使用道具 举报
梁志兵 发表于 2013-4-19 22:50
你的代码没有错

是错啦,我也知道传3没有错,但是传的31的话就会出错,因为这也是一种查找的情况啊,就像上面的朋友说的,是我的max取错了。谢谢啦
回复 使用道具 举报
刘印12 发表于 2013-4-19 11:03
报错的地方是十四行,你定义max的时候max的最大角标应该是arr。length-1.因为你传递的数组长度是6 而最大角 ...

恩,知道啦,谢谢
回复 使用道具 举报
yufeng47 发表于 2013-4-19 09:23
错误在:max = arr.length,应该为,max = arr.length-1。
分析哈角标的移动:

恩,知道啦,谢谢
回复 使用道具 举报
黑马伍哲沂 发表于 2013-4-19 09:05
这个代码里有三个问题:
第一,max应该是length-1;
第二,循环条件,应该要改,有两种该法,⑴改为while( ...

恩,知道啦,谢谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马