黑马程序员技术交流社区

标题: 自己写了两个使用递归实现拆半查找的方法,出问题了,... [打印本页]

作者: 孟浩然    时间: 2012-6-16 21:15
标题: 自己写了两个使用递归实现拆半查找的方法,出问题了,...
本帖最后由 孟浩然 于 2012-6-16 21:57 编辑
  1. /*
  2. 拆半查找 也可以说是二分查找
  3. 思路:先找到数组中的一个中间量,如果我要找的数比中间量大,那么就往中间量的右边继续使用这种方法查找
  4. 如果我要找的数比中间量小,那么就往中间量的左边继续使用这种方法查找

  5. 注意:拆半查找只能针对有序数列

  6. 定义函数:需要参数 一个数组和需要找的数
  7.                   需要返回找到的数的角标
  8. */

  9. class HalfSearch
  10. {
  11.         public static void main(String[] args)
  12.         {
  13.                 int[] arr={1,3,7,9,13};
  14.                 halfSearch_2(0,arr.length,13,arr);
  15.                 //halfSearch_1(arr,13);
  16.                 //System.out.println(index);
  17.         }

  18.         //方法一 传入数组和要查找的数
  19.         public static void halfSearch_1(int[] arr,int x)
  20.         {
  21.                 int min=0;
  22.                 int max=arr.length-1;
  23.                 int mid=(min+max)/2;

  24.                 if(min<=max)
  25.                 {
  26.                         if(x<arr[mid])
  27.                         {
  28.                                 max=mid-1;
  29.                                 halfSearch_1(arr,x);
  30.                         }
  31.                         else if(x>arr[mid])
  32.                         {
  33.                                 min=mid+1;
  34.                                 halfSearch_1(arr,x);
  35.                         }
  36.                         else if(x==arr[mid])
  37.                         {
  38.                                 System.out.println("找到角标为:"+mid);
  39.                         }
  40.                 }
  41.                 }


  42.         //方法二 传入最小、最大角标和要找的数以及数组
  43.         public static void halfSearch_2(int min,int max,int x,int[] arr)
  44.         {
  45.                 int mid=(min+max)/2;
  46.                 if(max>=min)
  47.                 {
  48.                         if(arr[mid]>x)
  49.                         {
  50.                                 halfSearch_2(min,mid-1,x,arr);
  51.                         }
  52.                         else if(arr[mid]<x)
  53.                         {
  54.                                 halfSearch_2(mid+1,max,x,arr);
  55.                         }
  56.                         else if(arr[mid]==x)
  57.                         {
  58.                                 System.out.println("找到角标为:"+mid);
  59.                                 //return mid;
  60.                         }

  61.                 }
  62.                
  63.         }

  64.         }



复制代码
就是上面两个方法,我觉得两个方法没有什么本质区别,但是第一个就是不能找到我要找的数,除了数组中间的那个数,第二个方法是用正常;另外两个都能编译通过,第一个运行时报错信息如下:
  1. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  2. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  3. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  4. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  5. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  6. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  7. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  8. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  9. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  10. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  11. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  12. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  13. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  14. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  15. at HalfSearch.halfSearch_1(HalfSearch.java:39)
  16. at HalfSearch.halfSearch_1(HalfSearch.java:39)
复制代码
就是这些 好多的,我就复制了一段,还有个问题就是如过把上面的方法改成可以返回角标的怎么改,我用不好return,希望有人给我改一下,我看看,用手机连笔记本上的网,发个帖子要半个小时,哎 悲剧啊
作者: 赵倩倩    时间: 2012-6-16 21:22
halfSearch_1 写的死循环了,每次都循环的调用 halfSearch_1(arr,x);没有递归跳出的条件


halfSearch_2 每次传入上下标的范围都在缩小,最后可跳出递归
作者: 孟浩然    时间: 2012-6-16 21:39
赵倩倩 发表于 2012-6-16 21:22
halfSearch_1 写的死循环了,每次都循环的调用 halfSearch_1(arr,x);没有递归跳出的条件

方法一不是有 min=mid+1和max=mid-1吗 它的最小角标和最大角标也是在变啊?
作者: 赵倩倩    时间: 2012-6-16 21:41
孟浩然 发表于 2012-6-16 21:39
方法一不是有 min=mid+1和max=mid-1吗 它的最小角标和最大角标也是在变啊?

因为这个并没有传递到下次递归的方法中去。所以,本质是没有效果的
作者: 王晓新    时间: 2012-6-16 21:47
  1. class HalfSearch
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 int[] arr={1,3,7,9,13};
  6.                 halfSearch_2(0,arr.length,13,arr);
  7.                 int a=halfSearch_1(arr,13);
  8.                 System.out.println(a);
  9.         }

  10.         //方法一 传入数组和要查找的数
  11.         public static int halfSearch_1(int[] arr,int x)
  12.         {
  13.                 int min=0;
  14.                 int max=arr.length-1;
  15.                

  16.                 while(min<=max)//
  17.                 {
  18.                                             int mid=(min+max)/2;
  19.                         if(x<arr[mid])
  20.                         {
  21.                                 max=mid-1;
  22.                         }
  23.                         else if(x>arr[mid])
  24.                         {
  25.                                 min=mid+1;
  26.                         }
  27.                         else
  28.                         {
  29.                                 return mid;
  30.                         }
  31.                 }
  32.                                 return -1;
  33.                 }


  34.         //方法二 传入最小、最大角标和要找的数以及数组
  35.         public static void halfSearch_2(int min,int max,int x,int[] arr)
  36.         {
  37.                 int mid=(min+max)/2;
  38.                 if(max>=min)
  39.                 {
  40.                         if(arr[mid]>x)
  41.                         {
  42.                                 halfSearch_2(min,mid-1,x,arr);
  43.                         }
  44.                         else if(arr[mid]<x)
  45.                         {
  46.                                 halfSearch_2(mid+1,max,x,arr);
  47.                         }
  48.                         else if(arr[mid]==x)
  49.                         {
  50.                                 System.out.println("找到角标为:"+mid);
  51.                         }

  52.                 }
  53.                
  54.         }
  55. }
复制代码
我对你的第一种方法改了一下,希望对楼主有帮助。。
作者: 王明明    时间: 2012-6-16 22:07
具体什么原因上面的都说了
我加一个我用FOR 写的方法
  1. class ceshi2
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 int[] arr={1,3,7,9,13};
  6.                 //halfSearch_2(0,arr.length,13,arr);
  7.                 halfSearch_1(arr,13);
  8.                 //System.out.println(index);
  9.         }

  10.         //方法一 传入数组和要查找的数
  11.         public static void halfSearch_1(int[] arr,int x)
  12.         {

  13.                 for( int min=0,max=arr.length-1;min<=max;)
  14.                 {               
  15.                                         int mid=(min+max)/2;
  16.        
  17.                         if(x<arr[mid])
  18.                         {
  19.                                 max=mid-1;
  20.                              
  21.                         }
  22.                         else if(x>arr[mid])
  23.                         {
  24.                                 min=mid+1;
  25.                               
  26.                         }
  27.                         else if(x==arr[mid])
  28.                         {
  29.                                 System.out.println("找到角标为:"+mid);
  30.                                                                 break;
  31.                         }
  32.                 }
  33.                 }

  34.         }
复制代码

作者: 胡大强    时间: 2012-6-16 23:48
/*
拆半查找 也可以说是二分查找
思路:先找到数组中的一个中间量,如果我要找的数比中间量大,那么就往中间量的右边继续使用这种方法查找
如果我要找的数比中间量小,那么就往中间量的左边继续使用这种方法查找
注意:拆半查找只能针对有序数列
定义函数:需要参数 一个数组和需要找的数
                  需要返回找到的数的角标
*/
class HalfSearch
{
        public static void main(String[] args)
        {
                int[] arr={1,3,7,9,13};
                //halfSearch_2(0,arr.length,13,arr);
                halfSearch_1(arr,13);
                //System.out.println(index);
        }
        //方法一 传入数组和要查找的数
        public static void halfSearch_1(int[] arr,int x)
        {
                int min=0;
                int max=arr.length-1;  ///
               
                while(min<=max)  ///
                {
      int mid=(min+max)/2;   
                        if(x<arr[mid])
                        {
                                max=mid-1;
                               // halfSearch_1(arr,x);
                        }
                        else if(x>arr[mid])
                        {
                                min=mid+1;
                               // halfSearch_1(arr,x);
                        }
                        else if(x==arr[mid])
                        {
                                System.out.println("找到角标为:"+mid);
        break;
                        }
                }
    }

    /*    //方法二 传入最小、最大角标和要找的数以及数组
        public static void halfSearch_2(int min,int max,int x,int[] arr)
        {
                int mid=(min+max)/2;
                if(max>=min)
                {
                        if(arr[mid]>x)
                        {
                                halfSearch_2(min,mid-1,x,arr);
                        }
                        else if(arr[mid]<x)
                        {
                                halfSearch_2(mid+1,max,x,arr);
                        }
                        else if(arr[mid]==x)
                        {
                                System.out.println("找到角标为:"+mid);
                                //return mid;
                        }
                }
               
        }*/
        }


///这是修改之后的代码。。。。。。。楼主可对照看一下。。。





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2