在Java中使用Recursion的BinarySearch

时间:2017-07-12 05:09:25

标签: java

我正在学习递归,所以试图通过实现BinarySearch算法来实践它。

public class BinarySearch {
    public int search(int[] items, int searchTerm, int startIndex, int endIndex) {
        int midIndex = (startIndex + endIndex)/2 ;
        System.out.println("Midpoint: "+midIndex);
        if(searchTerm == items[midIndex]) {
            return midIndex;
        } else if(searchTerm > items[midIndex]) {
            search(items, searchTerm, midIndex, endIndex);
        } else if(searchTerm < items[midIndex]) {
            search(items, searchTerm, startIndex, midIndex);
        } else {
            return -1;
        }
        return -1;
    }

    public static void main(String[] args) {
        BinarySearch bs = new BinarySearch();
        int[] items = { 1, 7, 9, 11, 22, 55, 67 };
        int index = bs.search(items, 7, 0, items.length-1);
        System.out.println(index);
    }

}

search是一个递归调用的方法,包含项目数组,我想要搜索并启动的值。项目可能存在的数组的结束索引。

首先,我得到中点,如果中点处的项目与searchTerm匹配,那么我将其返回。如果searchTerm大于中点值,则我再次调用搜索方法,中点为startIndex,数组中的最后一项为endIndex

同样,如果searchTerm小于中点的值,则将startIndex和midpoint作为开始和结束值传递给搜索。

让我们说,我想搜索7.在第一次迭代中,3将是中点,因此索引3处的值将是11.因为,7&lt; 11,搜索将再次调用,startIndex为0,endIndex为3.现在,中点为7,因此应返回7(即1)的索引。但是,返回的值为-1,这是不正确的。

当我尝试使用Eclipse调试器对其进行故障排除时,我发现即使在

处找到匹配项后也是如此
if(searchTerm == items[midIndex]) {
            return midIndex;
}

而不是退出方法,下面的代码被执行

else if(searchTerm < items[midIndex]) {
            search(items, searchTerm, startIndex, midIndex);
        }

然后它返回-1。我觉得这可能与递归有关,因为前面的search()调用仍然在堆栈中,因为代码的递归性质,它可能会弹出堆栈。但是,我无法理解它。使用递归实现BinarySearch的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

public int search(int[] items, int searchTerm, int startIndex, int endIndex)
{
  int midIndex = (startIndex + endIndex) / 2; 
  if (startIndex > endIndex)
    return -1;
  else if (searchTerm == items[midIndex]) 
    return midIndex;
  else if (searchTerm < items[midIndex]) 
    return search(items, searchTerm, startIndex, midIndex - 1);
  else // (searchTerm > items[midIndex]) 
    return search(items, searchTerm, midIndex + 1, endIndex);
}

在我使用midIndex ± 1的二进制搜索版本中:我这样做是因为在你的if语句中你已经检查items[midIndex]是否与searchTerm相等,那是&#39;为什么在下次通话中考虑items[midIndex]是不必要的。

答案 1 :(得分:0)

您没有返回递归调用。

    public int search(int[] items, int searchTerm, int startIndex, int endIndex) {
        int midIndex = (startIndex + endIndex)/2 ;
        System.out.println("Midpoint: "+midIndex);
        if(searchTerm == items[midIndex]) {
            return midIndex;
        } else if(searchTerm > items[midIndex]) {
            return search(items, searchTerm, midIndex, endIndex);
        } else if(searchTerm < items[midIndex]) {
            return search(items, searchTerm, startIndex, midIndex);
        } else {
            return -1;
        }
        return -1;
    }

<强>更新

如您所知,递归适用于方法堆栈。因此,当您在找到元素时没有返回值时,您的最终递归调用将始终返回-1,因为它是方法中的最后一行。

这就是你得-1的原因。