2012-05-28 83 views
1

作为一个示例,我正在开发一个简单的MySortedSet,它实现了SortedSet接口。它用一个简单的数组E []数组备份。用Java对数组排序

我有一个关于这几个问题:

这是类:(我不写整个代码,而不是相关的部分)

public class MySortedSet<E> implements SortedSet<E>, Iterator<E> { 

private E[] array; 
private Comparator<? super E> _comparator; 
private int size = 0; 
private int capacity; 

@SuppressWarnings("unchecked") 
public MySortedSet() { 
    this.capacity = 10; 
    this.array = (E[]) new Object[this.capacity]; 
    // this.array = Array.newInstance(Class<E> var,int size); 
    // We have to get Class<E> from outside caller. 
} 
} 

问题3:有一个解释构造函数,因为这是一个有序集合,因此假定的元素进行排序:

如果这个构造函数用于创建有序集合,它是假设d 该元素使用它们的自然排序来排序(即,E 实现了可比较的)。

它得到两个不同的构造函数。一个是无参数的,另一个接受Comparator<? super E>

public MySortedSet() { 
    this.capacity = 10; 
    this.array = (E[]) new Object[this.capacity]; 
    // this.array = Array.newInstance(Class<E> var,int size); 
    // We have to get Class<E> from outside caller. 
} 

public MySortedSet(Comparator<? super E> comparator) { 
    this._comparator = comparator; 
} 

如果comparator不过去了,自然排序应该使用,但我真的不知道如何完成它,因为我需要得到Comparator以某种方式来访问compare方法。你们是否请给我推荐一种叫它的方法,这样我就可以在比较sort方法时对它进行调用,以便对每个元素进行排序。

对于他们喜欢看整个代码的人,请参考以下地址:http://codepaste.net/4ucvsw这不是完美的,但我正在努力。

问题4:代码指南说:

因为搜索特定项目的最快方法是使用 二进制搜索,你必须确保集合中的项目在 随时排序。这可能不会像 似乎那样难以实现。当你插入一个新的项目时,你可以假设你已经排序的数组是 。因此,您只需在阵列中找到新项目所属的 位置,将所有 大于新项目一个槽位右移,然后插入新项目 。这被称为插入排序。

这里是sort方法逻辑。我需要进行二分查找以找到新物品所属的位置,以便我可以在该位置插入新物品并将另一个槽移到右侧。

但我不确定二进制搜索如何在我这里工作,因为我不知道我需要找什么。我得到的项目添加不是要找到的项目。相反,我认为将每个元素与我需要添加的元素进行比较,当我找到最后一个较小的第一个较大的项目时,我将获得第一个较大的项目的索引,将它们移动到右侧并在索引处添加新项目。

回答

1

问题3:

事实是,每一个收集工作与预定义的比较,这是对E隐式定义,让每一位将要使用的类来具体化类型参数Eimplement Comparable<E>。你正在寻找自然排序比较法是法

int compareTo(E other) 

必须由,你会用你的数据结构使用的类来实现。由于你的工作是没有关系的定义类与您的收藏使用,但只是对集合本身有什么你要做到这一点

public class MySortedSet<E> ... { 
    private Comparator<? super E> _comparator; 

    public int innerCompare(E e1, E e2) 
    { 
     if (_comparator != null) 
     return _comparator.compare(e1,e2); 
     else 
     return e1.compareTo(e2); 
    } 

    ... 

,让你在使用自定义的比较提供的情况下,自然否则。

ComparableComparator按照相同的原则工作,但第一个按名称状态附加到数据类,因此它是它的自然比较器。后者是用来替代的,因为它允许你定义一个自定义的排序方式来按照自然顺序以不同的方式排序元素。

问题4:

它的意思是,有一个排序数组的假设下,你只是必须保持这种约束有效每次插入后,寻找的时候,你会被允许做二进制搜索项目。

你必须只关注放置元件的正确的索引(你要添加的项目)。与查找元素有关的部分语句必须按以下方式解释:

如果您注意保持数组的排序顺序,可以通过确保您添加的每个元素都放在正确的位置(例如使用插入排序),那么当查看集合中是否包含元素时,可以对数组应用二进制搜索。

这是正确的,因为,如果数组进行排序,你可以肯定的是看阵列的部分的中间元素总是指向你到正确的方向,看看另一个元素确实包含在列表。

EG:

1, 2, 6, 11, 21, 30, 45 

您需要检查2,你可以在指数size()/2 = 3,这是11考虑元素。既然你已经知道数组已经排序,并且你可以在左半部分递归地做同样的事情,依此类推。

1

答3:

“自然顺序”的意思是元素都必须实现Comparable,使他们能够在不使用Comparator进行比较。关于给予调用者在Comparable元素和Comparator之间选择的棘手部分是你不能进行编译时检查,以确保它们至少满足这些要求之一。

Java的TreeSet同样暴露出一个构造函数一个Comparator和其他人没有。 TreeSet的合同本质上是抛出ClassCastException,如果您尝试插入非Comparable的元素(如果在创建它时没有提供TreeSetComparator)。无论你想使用这个策略还是另一个取决于你。

答4:

根据报价单的策略,你应该能够使用Arrays.binarySearch(Object[], Object)为此确切的目的。从这个方法的文档:

返回:搜索键的索引,如果它包含在数组中; 否则,(-(insertion point) - 1)。插入点被定义为键将被插入到数组中的点: ,大于该键的第一个元素的索引 ,或者如果数组中的所有元素 都小于指定的键,则为a.length。请注意,当且仅当找到密钥 时,此 可确保返回值> = 0。