【问题标题】:Block(array) implementation of a priority queue?优先级队列的块(数组)实现?
【发布时间】:2015-06-17 02:04:17
【问题描述】:

我现在正在准备考试,在样题考试中遇到了这个问题:

优先队列的块实现

如果我们事先知道优先级队列只需要满足少量离散优先级(比如 10 个),我们可以通过将优先级队列表示为一个数组来在恒定时间内实现优先级队列的所有操作of queues - 每个队列存储一个优先级的元素。请注意,虽然一个操作在优先级队列中的优先级数量可能是线性的,但该操作相对于整个数据结构的大小仍然是恒定的。

存储在此优先级队列中的对象不可比较。

我已经尝试过了,但我不知道应该如何为数组实现优先级队列分配优先级。

我也尝试过寻找解决方案,但我设法找到的只是使用 Comparable 的示例,我们在本课程中没有学习到这些示例。

问题:http://imgur.com/3mlBoW7

【问题讨论】:

    标签: java arrays priority-queue


    【解决方案1】:

    每个数组将对应不同的优先级。您的最低级别优先级数组将仅处理该优先级级别的对象。您的最高优先级数组将处理最高优先级的对象,依此类推。当您收到一个新对象时,将其放入与其优先级相对应的数组中。

    那么,对象不具有可比性并不重要,因为它们是根据数组的分层按优先级排序的。然后,当您寻找下一个要执行的元素时,您检查最高优先级的数组并查看是否有任何元素;如果不是,则移至下一个优先级,依此类推。

    我希望我能正确理解问题和您的问题;如果您对我的回答有任何其他问题,请告诉我。

    【讨论】:

    • 这是否意味着我们在数组中使用数组?你能给我一个如何实施它的开始吗?给您添麻烦了,先谢谢了!
    • 不一定。让我们从基础开始,假设您有 3 个优先级。优先级 1(高)、2(中)和 3(低)。你可以只创建 3 个单独的数组(或 ArrayLists,你喜欢)。
    • 嗯好吧,我先试试看,如果我有问题我会回来,但再次感谢您的时间和精力!你帮了大忙。
    • 别担心,很抱歉含糊其辞。我认为一旦你开始使用它,它会更有意义。如果您对实现某些功能有疑问或问题,请返回这里,我会看看是否可以提供帮助:)
    • 另外,补充一点,我认为是否将优先级数组存储在另一个数组中并不重要。这可能归结为偏好。这将使在 Java 中循环遍历您的队列更容易一些。
    【解决方案2】:

    根据 Imcphers 的回答,这将是 Java 中的一个简单实现。注意你不需要Comparable,因为enqueue需要一个额外的参数,即新增元素的离散优先级:

    public class PQueue<T> {
         public static final int MAX_PRIORITIES = 10;
         private ArrayList<ArrayDeque<T> > queues = new ArrayList<>();
         public PQueue() {
             for (int i=0; i<MAX_PRIORITIES; i++) {
                 queues.add(new ArrayDeque<T>());
             }
         }
         public void enqueue(int priority, T element) {
             // ... add element to the end of queues[priority]
         }
         public T dequeue() { 
             // ... find first non-empty queue and pop&return its first element
         }
         // ... other methods
    }
    

    这里,enqueue() 和 dequeue() 都是 O(1),因为你事先知道可以有多少个优先级,以及它们的值是什么(0 到 MAX_PRIORITIES-1),所以不需要排序,并且非空队列的搜索是恒定时间的(最多必须测试 MAX_PRIORITIES 个队列是否为空)。如果这些参数未知,最好的实现是使用

     private TreeSet<ArrayDeque<T extends Comparable> > queues 
          = new TreeSet<>(CustomComparator);
    

    CustomComparator 要求队列根据其第一个元素的自然顺序对自身进行排序,并且需要在每次调用 enqueue 后保持这些内部队列排序——这增加了入队/出队的复杂性到 O(log p),其中 p 是不同优先级的数量(因此是内部队列)。

    请注意,Java 的 PriorityQueue 属于同一个复杂度类,但通过实现其自己的内部优先级堆来避免 TreeSet / ArrayDeque 包装器造成的所有对象开销。

    【讨论】:

      猜你喜欢
      • 2021-08-14
      • 1970-01-01
      • 2012-11-26
      • 1970-01-01
      • 2015-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      相关资源
      最近更新 更多