我正在攻读考试(算法和数据结构),我正在努力让quicksort
为LinkedList
工作,但它正在给我ListIndexOutOfBoundsException
。
对于前一段时间的作业,我使用straightinsertion
来排序ArrayList
和Vector
,现在我想了解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
方法可以与Vector
或ArrayList
一起使用,我不知道为什么它不会与LinkedList
一起使用?
谢谢!
答案 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);
严格来说,还应该考虑到i
和j
在边界内(但我认为这不是必要的)。
它将解决异常问题,但我没有验证算法的正确性。
答案 1 :(得分:0)
Java中的big rules之一(以及一般的OO)是“接口代码,而不是实现”。现在,您正在编写LinkedList
接口的List
实现。保证此代码适用于任何列表(Vector
,ArrayList
等)的唯一方法是更改声明。例如:
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的建议是好的,虽然我没有测试它 - 但是它回答了你为什么这个代码没有像其他列表类型。这是因为您正在编写实现,您应该使用该接口。