我正在研究java中的Quicksort算法,我需要使用数组。
现在,我想让这个算法支持排序任何可比较数组。
我环顾四周,但围绕仿制药的大多数讨论和教程都令人困惑。简单地说,我不确定如何使这项工作。我已经确认Quicksort可以与Integers,Strings等一起工作,所以我需要做的就是让它适用于所有可比对象。但我的IDE告诉我,我不能引用非静态类型T"。我不确定这是什么意思。
public class QuickSort<T extends Comparable<T>> {
public static void Sort(T[] A) {
QuickSortRecursive(A, 0, A.length-1);
}
public static void QuickSortRecursive(T[] A, int p, int r) {
if( p < r ) {
int q = Partition(A, p, r);
QuickSortRecursive(A, p, q-1);
QuickSortRecursive(A, q+1, r);
}
}
public static int Partition(T[] A, int p, int r) {
String x = A[r];
int i = p - 1;
for(int j = p; j < r; j++) {
if(A[j].compareTo(x) <= 0) {
i = i + 1;
//swap A[i] with A[j]
T tmp = A[i];
A[i] = A[j];
A[j] = tmp;
}
}
//swap A[i + 1] with A[r]
T tmp2 = A[i + 1];
A[i + 1] = A[r];
A[r] = tmp2;
return i + 1;
}
}
简而言之,我在这里做错了什么?
答案 0 :(得分:2)
哦......好吧......
设计像
这样的通用类时class QuickSort<T extends Comparable<T>> { ... }
这只是意味着该类的实例可以(并且应该)使用具体的类型参数进行参数化。例如,您可以声明
QuickSort<String> sorter = new QuickSort<>();
静态方法不属于实例,因此这些方法对类型参数T
的含义没有任何线索。您可以自己制作这些静态方法:
static <T> void Sort(T[] A) { ... }
static <T> void QuickSortRecursive(T[] A, int p, int r) { ... }
static <T> int Partition(T[] A, int p, int r) { ... }
但这会导致其他一些错误。例如,您的方法Partition
中包含以下行:
String x = A[r];
由于参数A
的类型为T[]
,编译器不允许将数组的元素赋值给String
类型的变量(T
可以是任何东西) 。如果您已经知道,这些是字符串,为什么不简单地声明
static int Partition(String[] A, int p, int r) { ... }
这里不需要仿制药。
此外,OOP是关于对象(又名实例)的,而不是关于静态方法,这是一种更程序化的设计。因此,只需从所有方法中删除 static 关键字,然后将上述问题行更改为
T x = A[r];
然后一切都很好,你可以使用你的课程如下:
QuickSort<String> sorter = new QuickSort<>();
String[] strings = someStrings();
sorter.Sort(strings);
作为旁注:Java代码约定表示方法和变量名称应以较低的字母开头,因此请更好地命名方法sort
,quickSortRecursive
和partition
。
答案 1 :(得分:1)
您需要在每个方法而不是类上放置泛型类型声明,例如:
public static <T extends Comparable<T>> void sort(T[] A)
答案 2 :(得分:0)
两个问题:
对于静态字段和静态方法,它们在类的所有实例之间共享,甚至是不同类型参数的实例,因此显然它们不能依赖于特定的类型参数。
此处的代码:
public static int Partition(T[] A, int p, int r) {
String x = A[r];
你的数组是泛型类型(T []),你试图将类型为T的值分配给String?你可能应该这样做
public static int Partition(T[] A, int p, int r) {
T x = A[r];