用Java实现队列的最快方法

时间:2012-08-27 14:11:55

标签: java queue

我想知道应该对此代码进行哪些更改以减少执行时间。

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;
    }   
}

另外,我想知道是否实施queuesLinkedList是更快还是ArrayList还是其他任何数据结构。

5 个答案:

答案 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。

我认为这样可以节省浪费时间对列表进行排序。