整数的递归二进制搜索[重复]。

问题描述 投票:0回答:1

我试着用递归实现了二进制搜索的分而治之技术。下面可以看到它的代码。我想当程序运行时,我得到了堆栈溢出。如果有人能找到解决方法,我将非常感激为什么会发生这种情况。

public class binarySearch{
    public static void main(String[] arguments){
        int[] array = new int[]{1,2,3,4,5,6,7,8,9};
        int findNum = binSearch(array, 9, 0, array.length-1);
    }

    public static int binSearch(int[] array, int searchNum, int left, int right){
        int foundIndex = 0;
        boolean found = false;
        int mid = (right+left)/2;
        if(array[mid] == searchNum){
            found = true;
            foundIndex = mid;
        }
        else if(array[mid] > searchNum){
            right = mid;
            binSearch(array, searchNum, left, right);
        }
        else if(array[mid] < searchNum){
            left = mid;
            binSearch(array, searchNum, left, right);
        }

        if(found = true){
            return foundIndex;
        }
        else{
            return -1;
        }
    }
}
java recursion stack-overflow binary-search
1个回答
0
投票

你的实现逻辑是错误的,因此你的代码会运行到无限递归。正确的代码应该如下----------。

public class binarySearch{
    public static void main(String[] arguments){
        int[] array = new int[]{1,2,3,4,5,6,7,8,9};
        int findNum = binSearch(array, 9, 0, array.length-1);
    }

    public static int binSearch(int[] array, int searchNum, int left, int right){
        if(left>right)
            return -1; // We have now tried the full binary search and unable to find the element
        int mid = (right+left)/2;
        if(array[mid] == searchNum){
             return mid;
        }
        else if(array[mid] > searchNum)
            return binSearch(array, searchNum, left, mid-1); // <-- Here you were calling 
                                                             //binSearch(array, searchNum, left, right); which made your code go into infinite recursion

        else if(array[mid] < searchNum)
            return binSearch(array, searchNum, mid+1, right); //<-- you were calling 
                                                              //binSearch(array, searchNum, left, right); which made your code go into infinite recursion           
    }
}

上面的代码如果在数组中找到了元素,就会返回索引,否则就会返回-1。你也会注意到,我直接返回递归调用,比如--。return binSearch(array, searchNum, mid+1, right);而不只是打电话喜欢 - binSearch(array, searchNum, left, right);

希望能帮到你!


1
投票

目前发布的所有解决方案都存在计算mid时整数溢出的问题,同样的bug在JDK中潜伏了20多年。https:/ai.googleblog.com200606extra-extra-read-all-about-it-nearly.html。

int binarySearch(int arr[],int searchNum,int left, int right)
    {
        if (right >= left) {
            int mid = (left+right)>>>1; 
            if (arr[mid] == searchNum)
                return mid;
            if (arr[mid] > searchNum)
                return binarySearch(arr, left,mid - 1, searchNum);

            return binarySearch(arr, mid + 1, right, searchNum);
        }
        return -1;
    }

0
投票

你在叫 binSearch 但从不返回该调用的值。我想你是想把 found 在C语言中是一个静态变量,但在Java中没有这样的东西。即使你在另一个堆栈框架中修改了它,你当前堆栈框架中的值仍然会保持在 false.

更好的方法是使用尾部递归,直接返回结果。

public static int binSearch(int[] array, int searchNum, int left, int right){
    if (left == right) 
        return -1;
    int mid = (right + left) >>> 1;
    if(array[mid] == searchNum) 
        return mid;
    else if(array[mid] > searchNum) 
        return binSearch(array, searchNum, left, mid);
    else 
        return binSearch(array, searchNum, mid + 1, right);
}

你可以像这样调用该方法(right (应是排他性的)

int findNum = binSearch(array, -1, 0, array.length);

编辑: 在阅读了本报告后 回答 由Debapriya Biswas写的,我把这句话改成了: int mid = (right + left) / 2;int mid = (right + left) >>> 1; 以免失败时 right + left 的最大值,大于 int.

© www.soinside.com 2019 - 2024. All rights reserved.