在二进制搜索中,正在返回的内容是'

时间:2014-03-01 01:03:03

标签: java recursion

   private static Comparable search(Comparable[] a, Comparable key, int left,
            int right) {
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (key.compareTo(a[mid]) < 0) {                    
                return search(a, key, left, mid - 1);
            } else if (key.compareTo(a[mid]) > 0) {
                return search(a, key, mid + 1, right);
            } else {                        
                return a[mid];
            }
        }
        return "not found";

    }

我对算法和递归有一般性的了解,但此时却感到困惑。如果第一个if语句运行4次,那么4次返回的是什么?实际价值是多少?是否所有堆栈的值都相同?对于基本案例来说,这将是[mid]

更新代码

编辑:
我的问题是,每次&#34;返回&#34;在我到达基本案例并且堆栈上的所有调用完成之后,递归调用,它们的值是什么?如果第一个if语句运行两次,那么它在栈上有2个递归调用,等待返回值..当递归完成时返回值是什么

6 个答案:

答案 0 :(得分:1)

以下是代码正在做的事情:

  1. 如果仍有要检查的值(左侧索引小于或等于右侧索引),
  2. 找到中点
  3. 如果密钥小于中点的值,请调用搜索算法,但缩小范围(从左到中1)
  4. 如果密钥大于中点的值,请调用搜索算法但缩小范围(mid + 1到右)
  5. 如果密钥相等则返回值
  6. 如果步骤1的测试失败,则该键不能在该范围内,因此返回未找到
  7. 代码运行......你的问题是什么。这是一个完整的可执行程序,使用您的代码(完整)作为搜索方法。打印的行是bnot found     公共类BinSearch {

    public BinSearch() {
        // TODO Auto-generated constructor stub
    }
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        String[] info = { "a", "b", "c", "d", "e", "f", "g" };
        String find = "b";
        String findToo = "x";
    
        System.out.println(search(info, find, 0, info.length - 1));
        System.out.println(search(info, findToo, 0, info.length - 1));
        // TODO Auto-generated method stub
    
    }
    
    private static Comparable search(Comparable[] a, Comparable key, int left,
            int right) {
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (key.compareTo(a[mid]) < 0) {
                return search(a, key, left, mid - 1);
            } else if (key.compareTo(a[mid]) > 0) {
                return search(a, key, mid + 1, right);
            } else {
                return a[mid];
            }
        }
        return "not found";
    
    }
    
    }
    

答案 1 :(得分:1)

返回的是二元搜索的原理,即:如果键小于[mid],则外键(在该点右侧)变为中间值。基本上将项目数量分成两半,每次测试密钥与中间时间相同,直到达到while条件。

答案 2 :(得分:1)

“我的问题是每次”返回“都是递归调用的,在我到达基本情况并且堆栈上的所有调用完成后,它们的值是什么?

我添加了调试输出。你的循环中仍然存在一个错误,但这应该可以提供信息,并且它也应该回答你的问题。

   import  java.util.Arrays;
/**
   <P>{@code java DebuggingRecursiveFunctionXmpl}</P>
 **/
public class DebuggingRecursiveFunctionXmpl  {
   public static final void main(String[] ignored)  {
      Integer[] aiToSearch = new Integer[]{2, 2, 3, 5, 6, 7, 7, 10, 112};
      search(aiToSearch, 5);
      search(aiToSearch, 6);
      search(aiToSearch, -23);
      search(aiToSearch, 23223);
   }
   private static Comparable search(Comparable[] a, Comparable key) {
      return  search(a, key, 0, a.length);
   }
   private static Comparable search(Comparable[] a, Comparable key, int left, int right) {
      System.out.println("Searching for " + key + " in " + Arrays.toString(a) + ", from " + left + "-" + right);
      while (left <= right) {
         int mid = left + (right - left) / 2;
         if (key.compareTo(a[mid]) < 0) {
            return search(a, key, left, mid - 1);
         } else if (key.compareTo(a[mid]) > 0) {
            return search(a, key, mid + 1, right);
         } else {
            System.out.println("Found at index " + mid);
            return a[mid];
         }
      }

        System.out.println("Not found. Returning -1");
        return -1;
    }
}

输出:

[R:\jeffy\programming\sandbox\xbnjava]java DebuggingRecursiveFunctionXmpl
Searching for 5 in [2, 2, 3, 5, 6, 7, 7, 10, 112], from 0-9
Searching for 5 in [2, 2, 3, 5, 6, 7, 7, 10, 112], from 0-3
Searching for 5 in [2, 2, 3, 5, 6, 7, 7, 10, 112], from 2-3
Searching for 5 in [2, 2, 3, 5, 6, 7, 7, 10, 112], from 3-3
Found at index 3
Searching for 6 in [2, 2, 3, 5, 6, 7, 7, 10, 112], from 0-9
Found at index 4
Searching for -23 in [2, 2, 3, 5, 6, 7, 7, 10, 112], from 0-9
Searching for -23 in [2, 2, 3, 5, 6, 7, 7, 10, 112], from 0-3
Searching for -23 in [2, 2, 3, 5, 6, 7, 7, 10, 112], from 0-0
Searching for -23 in [2, 2, 3, 5, 6, 7, 7, 10, 112], from 0--1
Not found. Returning -1
Searching for 23223 in [2, 2, 3, 5, 6, 7, 7, 10, 112], from 0-9
Searching for 23223 in [2, 2, 3, 5, 6, 7, 7, 10, 112], from 5-9
Searching for 23223 in [2, 2, 3, 5, 6, 7, 7, 10, 112], from 8-9
Searching for 23223 in [2, 2, 3, 5, 6, 7, 7, 10, 112], from 9-9
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
        at DebuggingRecursiveFunctionXmpl.search(DebuggingRecursiveFunctionXmpl.java:22)
        at DebuggingRecursiveFunctionXmpl.search(DebuggingRecursiveFunctionXmpl.java:25)
        at DebuggingRecursiveFunctionXmpl.search(DebuggingRecursiveFunctionXmpl.java:25)
        at DebuggingRecursiveFunctionXmpl.search(DebuggingRecursiveFunctionXmpl.java:25)
        at DebuggingRecursiveFunctionXmpl.search(DebuggingRecursiveFunctionXmpl.java:16)
    at DebuggingRecursiveFunctionXmpl.main(DebuggingRecursiveFunctionXmpl.java:13)

答案 3 :(得分:1)

是的,它将在所有父调用中具有相同的值。 这样想,如果一个子调用找到了Object,那么它将返回它,而父调用将返回子调用返回的内容,接下来父调用成为另一个父调用的子调用,同样的情况发生。 很难用文字解释它,但它的正常逻辑和我们人类大脑不习惯的递归的魔力。

答案 4 :(得分:1)

跟踪它并退出代码。以这种方式看待它。假设你有一个这样的数组:

inputList = [1, 2, 3, 4, 5, 6, 7]

您正在寻找6.您知道输入源已排序,因此您可以进行二进制搜索。

二进制搜索应该转到中间元素并查看中间元素是否大于或小于目标。如果目标大于,则在所有大于元素的子列表上递归搜索。如果它小于您搜索小于目标的所有元素。

想象一下这是我们的堆栈跟踪:

 return binary_search_on(inputList)
 ------------------------
 binary_search_on: [1,2,3,4,5,6,7]
      var middle = 4
      4 == 6? nope. 
         so, is 4 < 6? nope, crap. 
            bah! 4 > 6 ? yes.  return binary_search_on([5, 6, 7])
 ------------------------
 binary_search_on: [5,6,7]
      var middle = 6
      6 == 6? cool. return 6

所以如果你回泡一下递归调用会返回什么?它返回6!使用最终返回值(6)替换您看到binary_search_on(...)的任何位置。

让我们完成剩下的工作:

 return binary_search_on(inputList)
 ------------------------
 binary_search_on: [1,2,3,4,5,6,7]
      var middle = 4
      4 == 6? nope. 
         so, is 4 < 6? nope, crap. 
            bah! 4 > 6 ? yes.  return 6

在这里,我将调用替换为`binary_search_on([5,6,7])6,因为它返回了什么。让我们继续:

 return 6

嗯,最终的回报是6,原因binary_search_on[1,2,4,5,6,7]现在也返回6。我们有它!

由于你多次调用“return”,可能会让人感到困惑,但是当递归找到最终结果时,它将返回最后一次递归调用的最终结果。

答案 5 :(得分:0)

没有运行四次。 'while'只执行一次。如果正文被执行,它会返回一些东西。 'while'应该是'if'。