【问题标题】:How to implement a priority queue using two queues如何使用两个队列实现优先级队列
【发布时间】:2026-01-05 06:15:01
【问题描述】:

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

面试后google了一下,发现可以用两个队列来实现,但是没找到怎么弄..

谁能给我解释一下。

提前致谢。

【问题讨论】:

  • 您在哪里找到了该声明?请张贴链接。
  • “队列”上有哪些方法/访问器可用,优先级队列需要什么?哪些操作需要什么效率?有很多可能的实现......
  • @Bergi 为什么你认为它来自一个网站,我明确提到我在面试中被问到这个问题,我是一名 B 技术学生,目前我正在为我的实习面试。如果您愿意,可以谷歌这个问题。
  • @Bergi 你是什么意思“'队列'上有哪些方法/访问器可用”,那些在正常队列中可用的方法/访问器,如果你不想帮助,请看兄弟,没有必要,还有其他人可以回答这个问题。
  • @Bergi 当我搜索“如何使用队列实现优先级队列”时,谷歌自动显示了建议“如何使用两个队列实现优先级队列"

标签: queue priority-queue


【解决方案1】:

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

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

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

现在添加元素

现在将剩余元素插入到 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->

【讨论】:

    【解决方案2】:

    基本解决方案

    使用两个队列

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

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

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

    【讨论】:

    • 为什么我不能使用单个队列并在队列中插入值和优先级作为结构。这样我就可以使用单个队列而不是两个队列来获取数据
    • 这不仅需要 O(n) 时间来获取顶部元素,还需要额外的 O(n) 空间。
    • 这个解决方案没有意义。为什么会被接受??
    【解决方案3】:

    当然有几种选择。我能想到的第一个仅使用 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())
    

    【讨论】:

    • 任何使用两个队列的解决方案??
    • 想不出比使用 2 个队列的线性实现更快的方法。
    【解决方案4】:

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

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

    java代码

    公共类_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");
        }
    
    }
    

    }

    【讨论】:

    • 队列表示先进先出。这里既是堆栈又是队列,既是FIFO又是FILO,有*First*Last两种方法。
    最近更新 更多