【问题标题】:How do I merge two queues into one queue?如何将两个队列合并为一个队列?
【发布时间】:2010-10-26 22:19:14
【问题描述】:

给定两个支持操作 enqueue/push_back、dequeue/pop_front 和 size 的队列

Q1: A1 A2 A3
Q2: B1 B2 B3

如何将它们合并到第三个队列中(也支持相同的操作),获得:

Q3: A1 B1 A2 B2 A3 B3

我对使用的算法更感兴趣,而不是任何特定的语言实现。

【问题讨论】:

  • 当一个队列比另一个队列更快耗尽时,您想做什么?停止?继续,忽略短队列中的任何缺失元素?继续,用空元素代替缺失的元素?

标签: algorithm merge queue


【解决方案1】:

这是一些伪代码:

Queue mergeQueues(Queue A, Queue B)
{
    Queue newQ;
    while(A.nonempty() OR B.nonempty())
    {
        if (A.nonempty())
            newQ.push(A.pop());
        if (B.nonempty())
            newQ.push(B.pop());
    }
    return newQ;
}

push 将一个元素插入队列,pop 删除队列中的下一个元素并将其返回。

请注意,这不适用于堆栈。你最终会倒退元素。如果您可以反转堆栈(例如,通过反复转移到另一个堆栈),那么它会起作用。

【讨论】:

    【解决方案2】:

    虽然两个队列都不是空的,但从 A 中取出一个项目并将其入队到 newQ。然后将一个项目从队列 B 中出列。如果其中一个队列(A 或 B)为空,则将另一个队列的其余部分出列并将每个元素入队到 newQ。

    【讨论】:

      【解决方案3】:

      似乎很适合递归实现:

      mergeQueues :: Queue a -> Queue a -> Queue a
      mergeQueues qa qb =
          merge qa qb emptyQueue
          where
              merge qa qb qr
                  | isEmpty qa = append qb qr
                  | otherwise  = move (merge qb) qa qr
              append q qr
                  | isEmpty q  = qr
                  | otherwise  = move append q qr
              move f q qr =
                  let (val,q') = pop q
                   in f q' (push val qr)
      

      请注意,我们只是在递归时来回翻转队列以便在它们之间交替,直到一个为空,此时我们只是从一个附加到另一个。

      请注意,虽然这比 ribond 给出的命令式版本长,但它只执行最少数量的isEmpty 检查。如果您不介意在稍微优化的版本中进行与他一样多的检查(将 isEmpty 值分配给变量以便在下面重复使用),您可以删除 append 函数并继续调用 merge 代替,在向merge 添加初始测试后,测试两个队列是否为空,如果是则终止递归。

      对于不熟悉Haskell的人,我们传入移动下一个要调用的函数(这是高阶函数式编程);在append 的情况下,这只是追加,在move 的情况下,这是一个“部分应用”的移动函数:它在我们调用move 之前应用第一个参数qb,然后move 应用其他两个参数。

      这听起来像是在日常业务编程中可能遇到的一项合理任务。但是,如果这是一个家庭作业功能,我建议你仔细研究一下上面的代码是如何工作的,我想你会学到一些东西。

      另外,上面的代码有可能有错误;证明它有效(或发现错误)将是一个很好的练习。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-16
        • 1970-01-01
        • 2019-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        相关资源
        最近更新 更多