我正在编排有序队列。在顶部有高优先级的元素,从最旧的到最新的排序。对于中间优先级的一部分元素和底部的低优先级元素的一部分也是如此。
当我想要对新元素进行排序时,我经常可以引用列表的最后一个元素。如果最后一个元素具有更高或相等的优先级,我的新元素将放在所有元素之后。
现在,在最后一个元素比我的新元素更低优先级的情况下,我不得不找到一种方法来遍历列表并找到谓词"优先级低的第一个元素。新元素"适用。然后我的新元素应该在那个位置。
我使用compareTo来比较两个元素。
我是一个初学者,我很难找到解决问题的方法。
非常感谢每一位帮助。
提前谢谢
我尝试过类似的事情:
public Queue<T> queue;
public OrderedQueue() {
queue = new LinkedList<T>();
}
public void enqueue(T newitem) {
int sss;
if (isEmpty()) {
((LinkedList<T>) queue).add(newitem);
}
else if (newitem instanceof BulkParcel) {
((LinkedList<T>) queue).addLast(newitem);
}
else if (newitem instanceof StandardParcel || newitem instanceof PriorityParcel) {
if (newitem.compareTo(((LinkedList<T>) queue).getLast()) == 0) {
((LinkedList<T>) queue).addLast(newitem);
}
else if (newitem.compareTo(((LinkedList<T>) queue).getLast()) < 0) {
((LinkedList<T>) queue).addLast(newitem);
}
else
for (Iterator<T> it = queue.iterator(); it.hasNext();) {
sss = newitem.compareTo(it.next());
((LinkedList<T>) queue).add((((LinkedList<T>) queue).indexOf(sss==-1)), newitem);
}
}
}
我能够完成我想要的。 这是我的新代码,适用于所有感兴趣的人。
public void enqueue(T newitem) {
int pos = -1;
int compVal = 2;
if (isEmpty()) {
((LinkedList<T>) queue).add(newitem);
}
else if (newitem.compareTo(((LinkedList<T>) queue).getLast()) == 0
|| newitem.compareTo(((LinkedList<T>) queue).getLast()) < 0) {
((LinkedList<T>) queue).addLast(newitem);
}
else {
for (Iterator<T> it = queue.iterator(); it.hasNext() && compVal != 1;) {
compVal = newitem.compareTo(it.next());
pos = pos + 1;
}
((LinkedList<T>) queue).add(pos, newitem);
}
}
我有一个自编的方法&#34; compareTo&#34;对于a.compareTo(b);,如果a小于b(这里是优先级),则返回-1,如果它们相等则返回0,如果a大于b,则返回1。
感谢所有帮助和详细解答! :)
答案 0 :(得分:1)
您正在查看插入排序。几乎可以肯定地在你的教科书中描述了......虽然你已经有了这个想法。
Queue
意味着特定的东西;它是用于投入元素并让队列决定放置它们的位置。 (例如在列表的末尾)。由于您要在特定位置插入,因此需要List。如果您不想要重复,则需要OrderedSet。将字段声明为最合适的字段并避免强制转换。
在每种情况下,您都应该注意确保您没有使用图书馆馆藏来规避教师设定的学习目标。
根据教师对您的要求,您可以使用其中一种,只需几行代码即可完成。或者他们可能都被禁止,你必须自己破解它。找出来!
我有建议让您更容易理解自己的代码。例如,走这一行:
if (newitem.compareTo(((LinkedList<T>) queue).getLast()) == 0) {
与
相同if (lastItemIsEqualTo(newItem)) {
如果您添加以下帮助方法:
private boolean lastItemIsEqualTo(T newItem) {
return newItem.compareTo(((LinkedList<T>) queue).getLast()) == 0;
}
向前推进,你可能最终得到:
if (lastItemIsEqualTo(newItem)) {
stuff...
}
else if (lastItemIsLessThan(newItem) {
stuff...
}
else for (Iterator<T> it = queue.iterator(); it.hasNext();) {
otherStuff...
}
相当于:
if (lastItemIsLessThanOrEqualTo(newItem)) {
stuff...
}
else for (Iterator<T> it = queue.iterator(); it.hasNext();) {
otherStuff...
}
但你也可以用if语句说出你真正想要完成的事情:
if (entireListComesBefore(newItem)) {
stuff...
}
else for (Iterator<T> it = queue.iterator(); it.hasNext();) {
otherStuff...
}
StandardParcel
vs BulkParcel
。是否需要两个班级?例如,如果BulkParcel
与StandardParcel
仅与单个项目相同,则可以使用Parcel
,但具有以下内容:
public boolean isABulkParcel() {
return parcel.size() > 1;
}
并且具有针对两者推广的算法。那你就不需要instanceof
。 instanceof
的用途很少,因为没有更好的解决方案。
sss = newitem.compareTo(it.next());
queue.add(queue.indexOf(sss==-1), newitem);
sss
毫无意义。这里有一个逻辑错误,如果您的变量名称更有意义,您会很快看到它。看:
boolean newItemGoesBeforeNextItem = newitem.compareTo(it.next()) == -1;
queue.add(queue.indexOf(newItemGoesBeforeNextItem), newitem);
现在你在最后一行看到问题了吗?那是boolean
,而不是数字索引。它会自动转换为对象Boolean
(注意大写)。因此,它尝试在列表中搜索该Boolean对象,但从未找到它。它正在这样做,基本上:
queue.indexOf(new Boolean(sss == 1))
这是一个非常重要的事情。如果您不理解,请花点时间仔细查看。
答案 1 :(得分:0)
在解决此问题之前,我建议您修复代码中的一些错误:
queue
投射到LinkedList
?在任何情况下,您调用的许多方法都是为Queue
实现的。但是,如果您特别需要List
方法,则应将其声明为List
。queue
应为private
。instanceof
通常表示您的班级结构有问题。在您的情况下,您几乎肯定会使用名为Parcel
的抽象类或接口声明您的类和队列,其中各个parcel是实现或扩展。Parcel
的自然排序(即实例本身实现compareTo
),或者您应该实现自己的比较器来封装您的优先级定义。它不应嵌入您的enqueue
方法中。例如,如果包裹的优先级发生变化会发生什么?理想情况下,您希望能够使用定义的比较器。希望有所帮助。