链表中字符串的二进制搜索

Binary Search of String within a linked list

我需要对具有各种数据类型的链表执行二进制搜索。下面的代码将无法编译。我似乎无法让 compareTo() 工作。

这里是链表class:

public class Contributor {

private String firstName;
private String lastName;
private String country;
private String phone;
private double contribution;
private int id;}

二分查找法如下。搜索需要使用二分法查找某个lastName。

 public void binarySearch(List<Contributor> l, String key) {
    System.out.println("Binary search.");

    int upperBound = l.size();
    int lowerBound = 1;
    int midpoint = (upperBound + lowerBound) / 2;
    int difference = upperBound - lowerBound;

    for (int i = 0; i < l.size(); i++) {
        if (key.compareTo(l.get(midpoint - 1))&& difference != 1) {
            upperBound = midpoint - 1;
            midpoint = upperBound / 2;
        } else if (key.compareTo(l.get(midpoint - 1)) && difference != 1) {
            lowerBound = midpoint + 1;
            midpoint = (lowerBound + upperBound) / 2;

        } else if (key.equals(l.get(midpoint - 1))) {
            midpoint = midpoint - 1;

            System.out.println("We found " + key + " at position " + midpoint + " in the list.");
            i = l.size();
        } else {
            System.out.println("We couldn't find " + key + " in the list.");
            i = l.size();
        }
    }
}

通过查看您的代码 l.get(midpoint-1) returns 贡献者对象不是字符串,并且 key.compareTo 方法只能接受字符串类型的参数。

compareTo() 函数 returns 整数值。所以试试

if(key.compareTo(str) < 0)

if(key.compareTo(str) > 0)

if(key.compareTo(str) == 0)

还将它与来自贡献者 class 的字符串进行比较,而不是与 class 本身进行比较。即

if(key.compareTo((l.get(midpoint - 1)).firstName)<0)

另一个逻辑错误是当你这样做的时候

midpoint = upperBound / 2;

您假设 lowerbound1。但它的值可能会在迭代中发生变化。所以也考虑一下

这里有一个逻辑错误 - 正如 Akshay 所说,你的密钥是 String,所以在 Contibutor 的列表中搜索它没有意义 - 你需要搜索 Contributor.

除此之外,二进制搜索的前提是列表已排序,这要求您的 Contributor 对象是 Comparable(或者至少您提供 Comparator.

我修改了您的代码以解决这些问题:

class Contributor implements Comparable<Contributor>{

    private String firstName;
    private String lastName;
    private String country;
    private String phone;
    private double contribution;
    private int id;

    public int compareTo(Contributor o) {
        return Integer.valueOf(id).compareTo(o.id);
    }
}

public class BinarySearch {
    /**
     * Performs a binary search for <code>key</code> in the list <code>l</code>.
     * 
     * @param l Ordered list of Contributors.
     * @param key Value to search for.
     */
    public void binarySearch(List<Contributor> l, Contributor key) {
        System.out.println("Binary search.");

        int upperBound = l.size();
        int lowerBound = 1;
        int midpoint = (upperBound + lowerBound) / 2;
        int difference = upperBound - lowerBound;

        for (int i = 0; i < l.size(); i++) {
            if (key.compareTo(l.get(midpoint - 1)) <0 ) {
                upperBound = midpoint - 1;
                midpoint = upperBound / 2;
            } else if (key.compareTo(l.get(midpoint - 1))>0 ) {
                lowerBound = midpoint + 1;
                midpoint = (lowerBound + upperBound) / 2;

            } else if (key.equals(l.get(midpoint - 1))) {
                midpoint = midpoint - 1;

                System.out.println("We found " + key + " at position "
                        + midpoint + " in the list.");
                i = l.size();
            } else {
                System.out.println("We couldn't find " + key + " in the list.");
                i = l.size();
            }
        }
    }
}

这应该可以修复您的编译错误,尽管正如其他人指出的那样,搜索逻辑本身存在一些错误。另请注意,binarySearch 方法的先决条件是对列表进行排序,并且应记录此要求。我已经添加了一个 javadoc 注释来解释这一点。