【问题标题】:Finding the minimum value in a queue, and deleting it from the queue查找队列中的最小值,并将其从队列中删除
【发布时间】:2017-08-06 22:04:59
【问题描述】:

几周后我有期末考试,我们的练习题之一是:

给定一个包含 N 个整数的队列,找出队列中的最小值并 从队列中删除它。完成后,其余值必须 保持原来的顺序。您只能使用队列操作,即 您无权访问数组或链接中的底层存储 列表。描述实现此操作的最省时的方法 并以 N 的形式给出顺序(大 O)。

我不知道该怎么做。

编辑:队列操作为“Enqueue”、“Dequeue”、“isFull”、“isEmpty”,如果是循环队列,则为“front”和“back”。

【问题讨论】:

  • 那么,根据您的考试定义,“队列操作”是什么?
  • 除了最小元素之外,弹出所有内容并将其推回队列怎么样?
  • 这本身并不是一个真正的编程问题。你会更幸运地向Computer Science S.E. 的人提问。
  • 哦,好的,谢谢 stybl!我不确定问你们是否更好!
  • @Jake 这样的问题在 Stack Overflow 上很好。

标签: algorithm data-structures queue


【解决方案1】:

如果您有一个队列并且只允许对其进行入队和出队,那么您可以在队列中找到任意值的唯一方法是执行尽可能多的出队以找到该特定值。如果您不知道该值在队列中的哪个位置,那么在最坏的情况下,您可能必须检查队列的所有 n 个元素,这需要 Θ(n) 时间。所以从这个意义上说,我们提出的任何解决方案都必须在最坏的情况下至少做 Θ(n) 的工作。

您可以这样做的一种方法是将队列想象成一个元素环,其中光标位于某个位置指示前端。如果您将一个元素出列然后立即将其重新入队,就好像您已将光标顺时针(或逆时针 - 这只是一个比喻)移动了一个点。因此,您可以考虑通过在队列中移动光标来解决此问题,直到找到要删除的元素,然后将其出队而不重新入队,然后将光标移动到您开始的位置。这是执行此操作的一种方法:

/* Store the number of elements in the queue, since it will change as
 * the loop runs. We want to visit each element exactly once.
 */
int numElems = queue.size();
for (int i = 0; i < numElems; i++) {
    ValueType elem = queue.dequeueMin();

    /* Remove the element if it matches the thing to get rid of, or,
     * equivalently, preserve the element if it isn't.
     */
    if (elem != theThingToRemove) {
        queue.enqueue(elem);
    }
}

这个算法总是做 Θ(n) 的工作 - 循环只访问每个元素一次并且做 O(1) 总工作 - 和 O(1) 总队列操作 - 每个元素。

有趣的事实:队列的这个比喻正是循环缓冲区背后的想法,它通常用于实现固定大小的队列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 2016-06-22
    相关资源
    最近更新 更多