如何修复此StackOverflowError?

时间:2014-02-25 04:02:44

标签: java recursion

背景: 该代码旨在使用递归二进制搜索算法来循环使用名称和数字的PhoneBookEntries的ArrayList。

我想我在这里使用我的搜索方法获得无限递归。我已经复制了代码。我很困惑:从我所知道的,每次,数组应该被分成两半并再次搜索直到找到搜索词,但该方法似乎没有正确终止。有什么提示吗?

编辑:我已根据以下评论的建议更改了代码,但它仍无效?

import java.util.ArrayList;


public class BinarySearcher {

    private ArrayList<PhoneBookEntry> entries;

    public BinarySearcher(ArrayList<PhoneBookEntry> entries)
    {
        this.entries = entries;
    }

    public int search(String find, int low, int high){

        int mid = (low + high) / 2;

        if(entries.get(mid).getName().compareTo(find) == 0){
            return mid;
        }

        if(entries.get(mid).getName().compareTo(find) < 0){
            return search(find, mid+1, high);
        }
        else if(entries.get(mid).getName().compareTo(find) > 0){
            return search(find, low, mid-1);
        }

        return -1;
    }
}

3 个答案:

答案 0 :(得分:3)

从一个不会改变的外部值初始化每个递归的低,高和中。所以他们实际上并没有变小。

pLow和pHigh从未使用过,但它们是您刚刚在之前的递归中使用过的新值。

答案 1 :(得分:1)

您的功能从不使用pLowpHigh个参数,因此它始终具有low = 0high = entries.size() - 1。您的函数应仅使用其参数,并且必须在第一次调用search之外进行这两次初始化。

说:

public int search(String find){
  return this.search(find, 0, entries.size() - 1 );
}

private int search(String find, int low, int high) {
    int mid = (low + high) / 2;

    if(entries.get(mid).getName().compareTo(find) == 0){
        return mid;
    }

    if(entries.get(mid).getName().compareTo(find) < 0){
        return search(find, mid+1, high);
    }
    else if(entries.get(mid).getName().compareTo(find) > 0){
        return search(find, low, mid-1);
    }

    return -1;
}

答案 2 :(得分:0)

您使用列表本身的最小和最大索引递归调用它,而不是将新参数基于传递给方法的参数。

public int search(String find, int pLow, int pHigh){
    // int low = 0; dont need, just use pLow
    // int high = entries.size() - 1; use pHigh instead
    int mid = (pLow + pHigh) / 2;

    if(entries.get(mid).getName().compareTo(find) == 0){
        return mid;
    }

    if(entries.get(mid).getName().compareTo(find) < 0){
        return search(find, mid+1, pHigh);
    }
    else if(entries.get(mid).getName().compareTo(find) > 0){
        return search(find, pLow, mid-1);
    }
    return -1;
}