2011-04-16 41 views
1

我必须实现一个通用的AVL树作为作业。它的定义如下:Java中的排序泛型

public class AVL<Key,Elem>; 

的问题是,我认为在某些时候,我不得不对键进行比较,以决定其中一个节点的身边,我分配的元素。为了这个作业的目的,Integers将被用作Keys。

由于没有其他限制或有关信息,我首先想到的是,Key将始终是一个Integer。但是,这使得通用的“关键”变得多余,我不认为这就是教师所期望的。所以,我认为最好的解决方案包括强制传递任何Key作为Key实现的比较器,或类似的东西(我真的从来没有用过Comparator,只是猜测),然后使用该比较器来比较Keys而不是使用==,<,>和!=运算符。但是,我不知道如何去做。任何提示?

在此先感谢。

回答

4

尝试public class AVL<Key extends Comparable<Key>,Elem>;并使用Comparable<T>接口所​​需的compareTo()方法,该方法由Integer执行。

+0

此解决方案和使用Comparator有什么区别?有人告诉我他是用它做的。感谢您的解决方案。 – bluehallu 2011-04-16 15:36:27

+1

我认为你可以用Comparator来混合Comparable。比较器将是一个对象,它可以比较任何类型的对象而无需实现“可比较”。但是,您的密钥不会实现“比较器”,但您可以将其作为单独的对象传递。另一方面,Comparable将对象标记为具有自然顺序(由'comparaTo()'的实现定义,如果你的键实现了,它们可以直接进行比较,注意所有Number对象('Integer', 'Double'等)以及'String'实现'Comparable'。 – Thomas 2011-04-16 15:53:13

+0

明白了,我将开始阅读关于Comparable接口的Java文档。谢谢。 – bluehallu 2011-04-16 15:58:33

2

SortedMapSortedSet实现标准Java API在任一使用Comparator<Key>并调用其compare(k1, k2)方法,或承担键实现Comparable<Key>,并调用k1.compareTo(k2)。大多数都提供,这取决于使用哪个构造函数。 (EnumMap/EnumSet不支持,因为它们只支持通过声明顺序枚举值的内置顺序。)

Comparable方法要求按键始终按照相同的方式排序,并且将用于具有规范排序(如整数)的键,您要使用此排序的键。

Comparator方法更加灵活,因为您可以对不同的地图使用相同的关键对象,因为它们的排列顺序不同,您可以将它用于您无法控制的关键点,或者没有规范的关键点排序(如列表,树/图等)。您还可以使用Collat​​or(这是一个实现比较器的类)以除unicode值之外的其他标准(例如,基于区域的)对其排序字符串键进行排序。

两者都需要您的密钥的总订单,但我想这也是您的AVL树所必需的。

这是一个比较器实现,可用于任何可比较的对象,因此您可以你可以使用它(可能是内部的)作为Comparable变体的适配器。

public static <X extends Comparable<X>> Comparator<X> makeComparator() { 
    return new Comparator<X>() { 
     public int compare(X left, X right) { 
      return left.compareTo(right); 
     } 
    }; 
} 
+0

事实上,我的Main类需要按不同的标准对项目进行排序,我需要为每种排序实例化各种AVL,并针对每种情况使用最好的AVL。我想这可以通过每次使用对象的不同字段作为Key和Comparable接口来完成,或者通过删除通用的“Key”并每次传递不同的比较器来比较每个期望的字段,但是由于它们给出了我们用通用的“钥匙”签名,他们想迫使我们使用第一种方法。不是吗? – bluehallu 2011-04-16 16:19:23

+1

你似乎有一个特殊情况,即关键是你提取的价值的一部分。在这种情况下,两种方法都可用。你也可以实现'SortedSet '并使用一个合适的比较器(但如果任务需要'',则同时使用)。它并不重要,其基本机制几乎相同。 – 2011-04-16 17:09:09