Java-实现排序算法';右';方式
我目前正在玩用Java实现各种排序算法的游戏,主要是为了好玩,但我正在努力解决如何做到“正确”。也就是说,我希望用户能够调用任何可比较的排序算法-Java-实现排序算法';右';方式,java,generics,sorting,insertion-sort,Java,Generics,Sorting,Insertion Sort,我目前正在玩用Java实现各种排序算法的游戏,主要是为了好玩,但我正在努力解决如何做到“正确”。也就是说,我希望用户能够调用任何可比较的排序算法-ints、longs、Strings、booleans(实际上,它们在Java中是可比的吗?),它们自己的类;无论什么问题是如何做到这一点 我正在考虑使用一个类来表示排序算法,因此使用一个通用列表或任何(list)将要排序的内容存储在内部。这还允许我使用多个构造函数,从而允许用户以各种形式传递数据-列表、数组等等。这是正确的方法吗?我目前的问题是,我不
int
s、long
s、String
s、boolean
s(实际上,它们在Java中是可比的吗?),它们自己的类;无论什么问题是如何做到这一点
我正在考虑使用一个类来表示排序算法,因此使用一个通用列表或任何(list
)将要排序的内容存储在内部。这还允许我使用多个构造函数,从而允许用户以各种形式传递数据-列表、数组等等。这是正确的方法吗?我目前的问题是,我不希望用户在排序时必须创建一个类,我更希望它能够像System.out.println
或类似的那样被调用
// Example:
int[] myInts = {5,4,3,2,1};
// This is what I do *not* want.
InsertionSort mySort = new InsertionSort();
int[] sortedInts = mySort.sort(myInts);
// This is more like what I want.
int[] sortedInts = Sorting.insertionSort(myInts);
我很抱歉问了一个看似基本的问题,但我只是在学习编程语言。这对于一个在软件公司做暑期工作的计算机专业二年级学生来说有点可笑,但你会惊讶于我的大部分工作所需要的编程知识是如此之少。。。通常更多的是设计知识
编辑:
为清楚起见,我的三个主要问题是:
- 是让用户创建一个类来进行排序更好,还是在用户导入的类中有一个静态方法更好
- 是否可以轻松处理基本数据类型和泛型对象?由于我希望能够处理实现Compariable(或类似)的任何泛型对象,这会导致原语出现问题(因为它们不实现任何东西;)
- 处理通用输入的最佳方法是什么?在尝试对它们进行排序之前,我应该检查哪些内容(例如,实现Comparable)
提供二进制搜索操作的方式为例。。。事实上
int[] sortedInts = Sorting.insertionSort(myInts);
更像java方式,即使我个人更喜欢
public class Sorting {
public static <DataType extends Comparable> Iterable<DataType> insertionSort(Iterable<DataType> data);
}
公共类排序{
公共静态Iterable insertionSort(Iterable数据);
}
确保输出数据的类型与输入数据的类型相同
数据输入数据是一个Iterable,以确保最大的兼容性。显然,使用列表将非常简单,因为它允许内部项目重新排序。然而,使用iterable可以确保此方法的实现者必须重新创建列表以对其进行修改,从而确保输入列表保持不变,而输出列表是另一个列表Iterable
compariable
(或类似)的任何泛型对象,这会导致基本体出现问题(因为它们不实现任何东西;)
您听说过吗?这是Java 5的一个特性,它使对象的主要类型“等价”。也就是说,int自动转换为Integer,正如您所知,Integer实现了compariable
处理通用输入的最佳方法是什么?在尝试对它们进行排序之前,我应该检查哪些内容(例如,实现Comparable)
注意,由于我的方法声明(,检查输入数据是否实现可比较不是由您完成的,而是由Jav编译器完成的,这样您的IDE就可以向您显示错误。我想您已经回答了自己的问题?如果您想公开一个静态方法,而不是让用户创建和对象并调用一个实例方法,那么只需这样做。
排序。insertionSort()
我觉得不错
在内部,它可以分派给任何你喜欢的东西。在内部,如果你想用类和多态性之类的东西来实现这一点,那就去吧。不过这似乎有点过分了。我不确定继承和多态性在这方面有多大帮助。我不确定这是否是你正在努力解决的问题……但这几乎是不可能实现的一种既适用于引用类型又适用于(实)基元类型的算法。原因是Java类型系统没有一个概念上的通用类型,它将基元类型和对象作为子类型 通常的解决方法是使用相应的包装类包装基本类型;例如,
int
的Integer
,boool
的Boolean
等等。这允许您实现(例如)一种排序算法,该算法适用于任何集合
或任何[]
当应用于大型整数数组时,这种方法存在性能/内存使用问题。要么使用性能指标,要么为每个基元类型分别实现算法及其支持类
(我说的几乎是不可能的,因为可以抽象一对数组元素的比较,并以一种不在接口中公开实际元素类型的方式交换一对数组元素;例如
public interface ArraySortAdapter {
public abstract int compareElements(Object array, int pos1, int pos2);
public abstract void swapElements(Object array, int pos1, int pos2);
}
并为不同的阵列类型提供不同的实现;例如
public class IntArraySortAdapter implements ArraySortAdapter {
public int compareElements(Object array, int pos1, int pos2) {
int[] intArray = (int[]) array;
if (intArray[pos1] < intArray[pos2]) {
return -1;
} else if (intArray[pos1] > intArray[pos2]) {
return +1;
} else {
return 0;
}
}
...
}
公共类IntArraySortAdapter实现ArraySortAdapter{
公共整数比较元素(对象数组、整数pos1、整数pos2){
public static <T> void swap(T[] a, int x, int y) {
T t=a[x];
a[x]=a[y];
a[y]=t;
}
public static <T extends Comparable<? super T>> void mergeInOrder(T[] src, T[] dst, int p1, int p2, int p3, int p4) {
if (src[p2].compareTo(src[p3])<=0) return; // already sorted!
// cut away ends
while (src[p1].compareTo(src[p3])<=0) p1++;
while (src[p2].compareTo(src[p4])<=0) p4--;
int i1=p1;
int i3=p3;
int di=p1;
while(di<p4) {
if (src[i1].compareTo(src[i3])<=0) {
dst[di++]=src[i1++];
} else {
dst[di++]=src[i3++];
if (i3>p4) {
System.arraycopy(src,i1,dst,di,p2-i1+1);
break;
}
}
}
System.arraycopy(dst, p1, src, p1, (p4-p1)+1);
}
public static <T extends Comparable<? super T>> void mergeSort(T[] src, T[] dst, int start, int end) {
if (start+1>=end) {
if (start>=end) return;
if (src[start].compareTo(src[end])>0) {
swap(src,start,end);
}
return;
}
int middle=(start+end)/2;
mergeSort(src,dst,start, middle);
mergeSort(src,dst,middle+1, end);
mergeInOrder(src,dst,start,middle,middle+1,end);
}
private static ThreadLocal<Comparable<?>[]> mergeSortTemp=new ThreadLocal<Comparable<?>[]>();
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> void mergeSort(T[] src) {
int length=src.length;
Comparable<?>[] temp=mergeSortTemp.get();
if ((temp==null)||(temp.length<length)) {
temp=new Comparable[length*3/2];
mergeSortTemp.set(temp);
}
mergeSort(src,(T[])temp,0,length-1);
}