【问题标题】:Is there any priority queue with O(1) insertion and removal when the elements are added in ascending order?当元素按升序添加时,是否存在具有 O(1) 插入和删除的优先级队列?
【发布时间】:2014-10-10 03:17:19
【问题描述】:

不能使用O(1) 插入和删除来创建优先级队列。毕竟,如果可能的话,可以对O(N) 中的列表进行排序。但是,假设元素是按升序添加的——也就是说,在特定的使用实例中,最后添加的元素始终是要删除的第一个元素。那么,是否有一个优先级队列会针对该用途进行持续查找/删除?

注意:我不是要求堆栈。我要求在这种特定使用模式下退化为不断查找/删除的优先级队列 - 类似于退化为几乎排序列表的 O(N) 最佳情况的排序算法。

【问题讨论】:

    标签: sorting data-structures queue priority-queue


    【解决方案1】:

    使用按优先级降序排列的链表。

    要删除一个元素,只需删除第一个元素。这总是 O(1)。

    添加元素:

    • 如果列表为空,只需插入元素即可。
    • 否则,遍历列表直到找到较低优先级的元素。在优先级较低的元素之前插入新元素。

    在新元素是最高优先级的情况下,这是 O(1)。此算法将检查第一个元素,并发现它不存在(在空列表的情况下)或低于新元素的优先级。

    【讨论】:

      【解决方案2】:

      当然没有什么能阻止你实现这样一个野兽。

      例如,当您将一个元素添加到当前为空的集合中,或者当项目仍以递增顺序进入时,您只需将项目添加到 堆栈。

      但是,如果您在任何时候添加一个优先级小于的项目,只需将所有堆栈条目移动到一个空队列(在下面所有提到的队列中,我的意思是优先级queue) 在幕后,在最后将您的新项目添加到该队列之前。

      清空队列后,您将再次恢复为默认堆栈。

      所以,基本上,伪代码是这样的。一、实例变量:

      class uberqueue:
          lastPrio = 0
          stack = []
          prioq = []
      

      然后是执行上述操作的put 函数:

          def put (item):
              # Empty, use stack.
      
              if stack.size() == 0 and prioq.size() == 0:
                  stack.push(item)
                  lastPrio = item.prio
                  return
      
              # Stacking and in order, add to stack.
      
              if stack.size() > 0 and item.prio >= lastPrio:
                  stack.push(item)
                  lastPrio = item.prio
                  return
      
              # Stacking and out of order, transfer stack to queue.
      
              while stack.size() > 0:
                  prioq.put(stock.pop())
      
              # Queueing, add to queue.
      
              prioq.put(item)
      

      最后,get 函数仅从当前活动的底层结构(堆栈或队列)中获取项目:

          def get():
              # Just get from whatever underlying structure is in use.
      
              if stack.size() > 0:
                  return stack.pop()
      
              return prioq.get()
      

      而且,如果您遵循优先级排序准则,您就有了一个数据结构,它可以为您提供 O(1) 的插入/检索性能,否则会恢复到优先级队列性能。


      事实上,如果堆栈和队列都提供查看下一个项目优先级的能力,您甚至可以完全摆脱堆栈到队列的传输。

      这样做的一种方法是当项目的优先级大于或等于顶部元素的优先级时将项目放入堆栈。这样可以确保堆栈中的所有项目都正确排序。所有乱序的项目都直接进入优先队列。

      get 功能必须稍作更改,查看堆栈和队列以查看哪个具有最高优先级,然后提取那个。

      这有点棘手,但在某些情况下可能会提供优势。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多