如何使用两个队列实现优先级队列

时间:2014-01-01 14:20:13

标签: queue priority-queue

在面试问题中,我被要求使用队列实施优先级队列

在采访之后我搜索了它,发现它可以使用两个队列实现,但我没有找到如何...

请任何人解释一下。

提前致谢。

4 个答案:

答案 0 :(得分:7)

使用优先级队列的主要优点是我们可以在恒定时间获得最小值/最大值。所以这是应该满足的第一个标准。我们只考虑关键价值观。 我们可以使用两个队列命名q1和q2来创建一个prioity队列 如果输入元素大于q1的顶部,则将其附加到q1 else

如果输入小于q1的顶部,则重复

从q1中删除元素并插入到q2,直到top大于该元素

现在添加元素

现在将剩余的元素插入到q2

so like input is 2 4 1 5 3
pass 1)
q1-> 2 
q2->  
pass 2)
q1-> 2 4
q2->
pass 3)
q1-> 
q2->1 2 4 // since 1 is less than top of q1 add it to q2 and then pop all the elements to q2
pass 4)
q1-> 
q2-> 1 2 4 5 //add it to q2 since it is larger than all the elements
pass 5)
q1-> 1 2 3 4 5//pop the elements smaller than q3 and then add the element and append the        remaining

q2->

答案 1 :(得分:3)

基本解决方案

使用两个队列

  1. 第一个包含所有元素
  2. 第二个包含第一个队列中元素的相应优先级

    • 插入:为每个元素插入第一个队列中的值,并在第二个队列中插入其优先级 时间复杂度 O(1)

    • 获取顶部元素:搜索第二个队列以获得最高优先级,第一个队列中的相应元素是优先级队列的顶部元素
      时间复杂度 O(n)

答案 2 :(得分:1)

当然有几种选择。我能想到的第一个只使用1个队列,但假设你知道队列的大小。

复杂性不是很好,插入是线性的,弹出是恒定的。

下面是伪python 3代码。

class PriorityQueue(Queue):

    def insert(self, item):
        for i in range(self.size):
            next = self.pop()
            if next < item:
                self.enqueue(next)
            else:
                self.enqueue(item)
                self.enqueue(next)
                break
        for i in range(i, self.size):
            self.enqueue(self.pop())

    def pop(self):
        return self.pop()

我使用名称'self.pop'从原始队列中取出第一个项目。 'self.enqueue'将一个项目放在原始队列的末尾。

工作原理:插入从队列中获取所有较小的项目,并将它们放在最后。当新项目最小时,将其放在最后。之后,只需将剩余的项目放在最后。

请注意,我没有将详细信息放在我的代码中,例如队列为空,可能已满的情况......这段代码不起作用,但它应该传达这个想法。

python 3中的工作解决方案:

from queue import Queue

class PriorityQueue(Queue):

    def insert(self, item):
        if self.empty():
            self.put(item)
            return
        i = 0
        size = self.qsize()
        n = self.get()
        while item > n and i < size:
            self.put(n)
            n = self.get()
            i += 1
        if i == size:
            self.put(item)
            self.put(n)
            for i in range(size): self.put(self.get())
        else:
            self.put(item)
            self.put(n)
            for j in range(i + 1, size): self.put(self.get())

答案 3 :(得分:0)

这是我遇到的一些问题。 使用2个队列实现maxQueue

出队时间复杂度 - O(1) 入队时间复杂度 - O(n)

java中的代码

public class _01_MaximumQueue {

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub

}

public class QueueWithMax<T extends Comparable<T>> {
    Queue<T> enteries = new ArrayDeque<T>();
    Deque<T> candidatesForMax = new ArrayDeque<T>();

    public void enqueue(T x) {

        enteries.add(x);

        if (candidatesForMax.peekLast().compareTo(x) < 0) {
            candidatesForMax.removeLast();
        }
        candidatesForMax.addLast(x);

    }

    public T dequeue() {

        if (!enteries.isEmpty()) {
            T result = enteries.remove();
            if (candidatesForMax.peekFirst().equals(result)) {
                candidatesForMax.removeFirst();
            }
            return result;
        }

        throw new IllegalStateException("called Degueue() on empty Queue");
    }

    public T max() {
        if (!candidatesForMax.isEmpty()) {
            return candidatesForMax.peekFirst();
        }
        throw new NoSuchElementException("No element");
    }

}

}