【问题标题】:Binary Search: Program doesn't terminate二进制搜索:程序不会终止
【发布时间】:2022-01-09 14:56:06
【问题描述】:

我一直在尝试学习算法,作为其中的一部分,我一直在尝试编写二进制搜索代码,逻辑似乎很好。代码不会终止,IDE 永远保持空闲状态。我不明白我做错了什么。任何帮助表示赞赏。提前致谢!

public class BinarySearch {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        int no = 5;
        System.out.print(binSearch(arr, no, 0, arr.length - 1));


    }

    private static boolean binSearch(int[] arr, int no, int start, int end) {
        while(start <= end) {
            int mid = (start + end) / 2;
            if (arr[mid] == no) {
                return true;
            } else if (no > arr[mid]) {
                binSearch(arr, no, mid + 1, end);
            } else if(no < arr[mid]) {
                binSearch(arr, no, start, mid - 1);
            }
        }
        return false;
    }
}

【问题讨论】:

    标签: algorithm binary-search


    【解决方案1】:

    您在两个递归调用中缺少return

    private static bool binSearch(int[] arr, int no, int start, int end) {
        
        while(start <= end) {
            int mid = (start + end) / 2;
            if (arr[mid] == no) {
                return true;
            } else if (no > arr[mid]) {
                return binSearch(arr, no, mid + 1, end);
            } else if(no < arr[mid]) {
                return binSearch(arr, no, start, mid - 1);
            }
        }
        return false;
    }
    

    你也可以考虑把它写成非递归循环。

    【讨论】:

    • 非常感谢。由于我已经在找到时返回 true,在未找到时返回 false,您能否解释一下添加 return 使其工作?
    • 当我调试代码时,我看到它在返回 true 后并没有终止。它转到下一个 else if。知道为什么吗?
    • @Harsha 学习如何使用调试器、设置断点和单步调试代码会很好。或者添加打印语句,这样你就可以看到它在做什么。当您调用 binsearch 而不返回值时,它不会终止循环,因此它只会继续运行并调用方法并忽略结果。
    • @Harsha:它从递归调用返回到外部调用,然后忽略结果。调试时查看调用堆栈。
    【解决方案2】:

    好吧,我想我们回顾一下递归

    binSearch(arr, num, start, end){
    
        while (start<=end){
            int mid = (start+end)/2;
            if (arr[mid] == no) {
               return true              #when it finally matches return true 
            }
    
    
            else if (arr[mid] > no) {
                binSearch(arr, no, start, mid-1)  #call binSearch for new value
    
            }
        }
    }
    

    为了说明递归,假设我们想要一个输入 A 的值 B。现在将一个节点或某个点想象为代表我们输入 A 的原点。对于 A 之后的每个点或节点,我们都采取了一些步骤来找到值 B

    一旦我们找到了我们想要的值,我们的方法的结构就可以用一个具有一个方向的图来说明。 A --> C --> --> D --> B

    这基本上就是递归的工作原理。现在首先,让我们看一下您的 else if 语句。当您的参数满足 else if 条件之一时,您将调用 binSearch 方法。

    这基本上是创建一个新的起点,而不是从最初的起点开始。因此,假设在第 3 次迭代中,您最终满足了布尔条件并返回 true。但是它在哪里返回 true 呢?

    仅对 binSearch 进行的最后一次调用或最近一次调用。让我们称之为迭代 2。

    现在,一旦创建了返回值,它就会简单地转到下一个代码块,这会将我们带到您的 while 循环中。您的代码可以移动到下一个代码块(返回 false 值)的唯一方法是跳出 while 循环,即。让你的起始值大于你的结束值。

    但是请记住,我们正在进行第 2 次迭代。第 2 次迭代被赋予了满足 while 循环的 start 和 end 值,因此它再次循环,并且任何 else-if 语句迭代 2 在返回 true 的最终迭代之前登陆,它将无限期地重复。

    上面提到的显而易见的解决方案是在调用之前放置“return”,因为这将一直返回到对 binSearch 的原始调用。

    另外,while 循环不是必需的,除非您在没有递归的情况下执行它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-09
      • 2020-12-25
      • 1970-01-01
      • 1970-01-01
      • 2019-03-03
      • 2016-04-16
      • 1970-01-01
      • 2017-09-23
      相关资源
      最近更新 更多