【问题标题】:What is the efficient way of implementing a queue?实现队列的有效方法是什么?
【发布时间】:2011-03-20 07:21:25
【问题描述】:

什么是实现队列的有效方法,以便了解它是如何实现的?

编辑: 我查看了 stl::queue 代码以了解它是如何实现的,但模板代码使其难以理解。毕竟有比使用链表更有效的方法。

【问题讨论】:

  • 什么是低效的方法?您要么实现队列,要么不实现:)
  • 如果您希望世界上最好的程序员花时间为这个问题提供有价值的答案,那么您确实需要更加具体并更加小心地提出您的问题。
  • 在 C++ 中,但我想了解它是如何实现的。
  • 请编辑您的问题,而不是直接回答 cmets。当人们试图回答问题时,这将有所帮助。

标签: c++ queue


【解决方案1】:

最有效的方法是让别人来做。

C++ 和 C#(以及 .NET 等)在它们的本地库中都有一个。

【讨论】:

  • 我查看了 stl::queue 代码以了解它是如何实现的,但模板代码使其难以理解。毕竟,使用比使用链接的 lisk 更有效。
【解决方案2】:

当然,对于任何生产代码,您都应该依赖已经经受住时间考验的健壮库实现。

也就是说,对于自学来说,自己写一个会很有趣。我以前做过。

我所知道的最有效的方法是使用与大多数可调整大小的集合在内部所做的类似的方法:存储一个数组,当集合的大小达到数组的长度时,它的大小会根据需要增加(通常翻倍)。

不过,队列与普通集合有点不同,因为您希望能够从推送元素的另一端弹出。

显然,删除第一个元素并将所有其他元素向下移动一个索引将是昂贵且毫无意义的。因此,您可以自己跟踪开始和结束索引。当集合到达数组的末尾时,您使用 % 开始将元素推回到开头。

关键是简单地计算出你的数学,以便你处理所有情况,例如,当队列已满时正确增长数组,正确检查边界,在每次弹出时增加起始索引(或循环回 0)等。

显然,我上面描述的设计有很多限制:例如线程安全。但是对于一个简单的、单线程的、高效的实现来说,这是一个很好的起点。

祝你好运——如果/当你有一个你认为有效的代码时,我也建议你发布你的代码!

【讨论】:

  • 谢谢,这种方法也适用于循环队列。
  • 当然。阅读有关 Deques 会告诉你一些关于这些东西的信息;它们通常被实现为循环缓冲区(如 Dan Tao 所建议的)或链表。后者通常效率较低。
  • @Passionate:是的,实际上任何队列实现都可以简单地包装以提供循环队列的功能(我假设“循环队列”是指长度有上限的队列?) .或者,您当然可以从一开始就采用这种方式。
【解决方案3】:

在最一般的意义上,如果您维护一个frontrear 指针,那么链表将是您最好的选择。在这种情况下,队列插入和删除是一个O(1) 操作。您还可以使用数组实现一个并维护前后索引。数学稍微复杂一些(当您插入或删除时,您必须考虑“包装”以避免超出范围)。

【讨论】:

    【解决方案4】:

    如果您可以接受队列的最大大小,circular buffer 将非常有效。因为库函数不能假定最大大小,所以它们不使用这种技术。

    【讨论】:

    • 您能否介绍一下库函数是如何实现的?
    • @Passionate,我只对 std::queue 非常熟悉。它封装了任何实现frontbackpush_backpop_front 的容器。因为这些容器一开始是空的并根据需要增长,所以队列也是如此。
    【解决方案5】:

    对于 C++,stl::queue.

    【讨论】:

      【解决方案6】:

      你明白how a queue works吗?

      你明白how stl queue works吗?

      你明白"most efficient" is an abstract concept that can't hold true for every case?

      如果你掌握了这一切,“最高效的 c++ 队列算法”就会来找你

      【讨论】:

        【解决方案7】:

        如果您需要线程感知队列实现,您可以尝试my own library。它尚未完成,但有据可查。

        编辑:它是由链表实现的。

        【讨论】:

          【解决方案8】:

          一次可能有多少个线程正在读取您的队列?有多少人可以同时写它?一个线程可以读取而另一个线程正在写入吗?您想为队列的最大大小预先分配空间吗?您是否需要一种方法让读取器在等待数据时阻塞,或者让写入器在队列已满时阻塞?您希望每秒有多少对象通过队列?

          最佳方法将取决于这些问题的答案。

          【讨论】:

            【解决方案9】:

            如果您的主要目标是了解它是如何实现的,那么您应该使用链表。使用它们很有趣,并且真正展示了与顺序数组的区别,并教授了很多关于内存的知识。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-06-25
              • 1970-01-01
              • 1970-01-01
              • 2017-03-12
              • 1970-01-01
              • 2010-11-13
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多