我想知道应该对此代码进行哪些更改以减少执行时间。
import java.util.*;
public class ExamPeekableQueueImpl <E extends Comparable<E>> implements ExamPeekableQueue<E> {
LinkedList<E> li = new LinkedList<E>();
public ExamPeekableQueueImpl(){
}
public void enqueue(E e){
if(li.isEmpty()){
li.add(0, e);
}
else
li.add(e);
}
public E dequeue(){
li.pollFirst();
return null;
}
public void printlist(){
System.out.println(li.toString());
}
public E peekMedian(){
int var = (((li.size())/2)+1);
Collections.sort(li);
//Integer var2 = li.get(var);
System.out.println("the median is:" + li.get(var-1));
return null;
}
public E peekMaximum(){
Collections.sort(li);
System.out.println("the maximum is:" + li.getLast());
return null;
}
public E peekMinimum(){
Collections.sort(li);
System.out.println("the minimum is:" + li.getFirst());
return null;
}
public int size(){
li.size();
return 0;
}
}
另外,我想知道是否实施queues
,LinkedList
是更快还是ArrayList
还是其他任何数据结构。
答案 0 :(得分:3)
这是一个加载的问题。
你想加快什么操作?现在,你的peekMin / Max / Mid代码很慢,因为你每次都必须排序。但是,您的插入代码很快。如果需要,可以在内部维护已排序的数据结构。这会减慢你的插入方法,但加快你的偷看方法。在这样的操作之间经常需要权衡速度。很少能够加速某些数据结构上的所有操作,因此您需要选择您认为常见的操作,并优化这些操作。
这是关于你想加快哪些操作。
答案 1 :(得分:2)
目前, O(1)用于插入, O(nlogn)用于getMin/getMax/getMedian
。您可以使用排序数据结构将 logn 从getter移动到插入部分。或者您可以保持插入不变,并通过在列表中进行线性搜索并仅存储最小值来优化getMin/getMax
。对于getMedian
,您无需做任何事情,因为需要一个有序的集合。
进一步优化将存储最小值/最大值并在每个插入步骤期间更新两个值。这不会对插入进行任何(非常量)更改,并会将getMin/getMax
缩减为 O(1)。 (感谢 Tedil )
同样适用于getMedian
,您可以在其中保存与链接列表并行的排序列表。然后,您可以简单地从该列表中间选择中位数。当然,这会将插入时间更改为 O(logn)或更糟(取决于您使用的列表),并且还会使存储空间量增加一倍。因此,它比getMin/getMax
更优惠。
答案 2 :(得分:0)
回答你的问题。请查看this主题,了解在结构中使用数组或链表之间的区别。
另外,作为建议,在声明结构时,始终使用接口作为类型,以便您可以在不影响功能的情况下更改实现。
答案 3 :(得分:0)
取决于。
实际上,大多数人回答/评论都没有意识到,Collections.sort在近乎排序的列表中给出了N个性能。 (如果列表没有完全排序,则N log N是性能。)
正如其他人所说,也许你应该在更改列表而不是阅读列表时进行排序。也许你应该使用有序集而不是列表。 (如果您确实需要一个列表来保存项目的多个副本,请考虑使用“有序地图”并将出现次数作为值。)
您还可以考虑创建一个存储Collection的对象,并在不对其进行排序的情况下跟踪min和max。如果找到中位数很少或者你可以摆脱需要中位数,这将很有效。
答案 4 :(得分:0)
在peekMaximum()和peekMinimum()方法中,您可以直接使用方法Collections.max(li)
和Collections.min(li)
来代替排序LinkedList。
我认为这样可以节省浪费时间对列表进行排序。