Java:LinkedList上的QuickSort给了我一个例外

时间:2013-01-25 14:37:02

标签: java linked-list quicksort

我正在攻读考试(算法和数据结构),我正在努力让quicksortLinkedList工作,但它正在给我ListIndexOutOfBoundsException

对于前一段时间的作业,我使用straightinsertion来排序ArrayListVector,现在我想了解QuickSor t(理论上我做的) LinkedList。 我对linkedlist不太熟悉,但它与ArrayList不应该太过不同?

public class Sort {

public static void quickSort(LinkedList<Oseba> a) {
    sort(a, 0, a.size() - 1); // this is line 16
}

public static void sort(LinkedList<Oseba> a, int l, int r) {
    int i = l;
    int j = r;

    Oseba x = a.get((l + r) / 2), w;

    do {
        while (a.get(i).mlajsi(x)) {
            ++i;
        }
        while (x.mlajsi(a.get(j))) { // this is line 31
            --j;
        }
        if (i <= j) {
            w = a.get(i);
            a.set(i, a.get(j));
            a.set(j, w);
            ++i;
            --j;
        }
    } while (i <= j);

    if (l < j) {
        sort(a, l, j);
    }

    if (i < r) {
        sort(a, i, r);
    }
}
}

Oseba表示“一个人”,它是我为测试各种方法而编写的一个类(如排序,比较)

public class Oseba implements Comparable<Oseba> {

protected String priimekIme; //surnameName
protected int letoRojstva; //year of birth
protected Spol spol; //gender (enum)

public Oseba(String priimekIme, int letoRojstva, Spol spol) {
    this.priimekIme = priimekIme;
    this.letoRojstva = letoRojstva;
    this.spol = spol;
}

@Override
public int compareTo(Oseba o) {
    if (this.letoRojstva < o.letoRojstva) {
        return -1;
    } else if (this.letoRojstva > o.letoRojstva) {
        return 1;
    } else {
        return this.priimekIme.compareTo(o.priimekIme);
    }
}

public boolean mlajsi(Oseba o) { //younger
    return (o.letoRojstva - this.letoRojstva <= 0);
}

@Override
public String toString() {
    String s = priimekIme + ", " + spol.getKratko() + ", " + letoRojstva;
    return s;
}
}

这是我得到的错误:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: -1, Size: 6
    at java.util.LinkedList.checkElementIndex(LinkedList.java:553)
    at java.util.LinkedList.get(LinkedList.java:474)
    at javaapplication1.Sort.sort(Sort.java:31)
    at javaapplication1.Sort.quickSort(Sort.java:16)
    at javaapplication1.JavaApplication1.main(JavaApplication1.java:55)
Java Result: 1

quicksort方法可以与VectorArrayList一起使用,我不知道为什么它不会与LinkedList一起使用?

谢谢!

2 个答案:

答案 0 :(得分:1)

嗯,你不要在循环中检查边界。

   while (a.get(i).mlajsi(x)) {
        ++i;
    }
    while (x.mlajsi(a.get(j))) { // this is line 31
        --j;
    }

应该是

   while (i <= r && a.get(i).mlajsi(x)) {
        ++i;
    }
    while (j >= l && x.mlajsi(a.get(j))) { // this is line 31
        --j;
    }

} while (i <= j);

严格来说,还应该考虑到ij在边界内(但我认为这不是必要的)。 它将解决异常问题,但我没有验证算法的正确性。

答案 1 :(得分:0)

Java中的big rules之一(以及一般的OO)是“接口代码,而不是实现”。现在,您正在编写LinkedList接口的List实现。保证此代码适用于任何列表(VectorArrayList等)的唯一方法是更改​​声明。例如:

public static void quickSort(LinkedList<Oseba> a) {

应该成为

public static void quickSort(List<Oseba> a) {

与sort类似:

public static void sort(List<Oseba> a, int l, int r) {

现在,每当你宣布一个人时,它应该是这样的:

List<Oseba> a = LinkedList<Oseba>();

但是在LinkedList的位置,您可以替换任何其他类型的列表。

这并没有回答为什么你的代码失败的问题 - 我认为UmNyobe的建议是好的,虽然我没有测试它 - 但是它回答了你为什么这个代码没有像其他列表类型。这是因为您正在编写实现,您应该使用该接口。