【问题标题】:Efficient way to sort a concatenation of lists (STL), merge sort hint, partially sorted对列表串联 (STL) 进行排序、合并排序提示、部分排序的有效方法
【发布时间】:2010-11-21 09:47:54
【问题描述】:

我有一种情况,我得到一个已经部分排序的值列表。我的最终列表中有 N 个块,每个块都是排序的。所以我最终得到了一个这样的数据列表(斜线只是为了强调):

1 2 3 4 5 6 7 8 / 1 2 3 4 5 / 2 3 4 5 6 7 8 9 / 1 2 3 4

我将这些作为一系列指向对象的指针放在一个向量中。目前我只使用std::sort 和自定义比较器进行排序。我猜这是次优的,因为我的序列是一些退化的情况。

是否有任何其他 stl 函数、提示或其他方法可以用来提供最佳类型的此类数据? (Boost 库也可以)。

虽然我不能轻易分解输入数据,但我当然可以确定子序列的开始位置。

【问题讨论】:

  • 我相信对于链表,合并排序是为数不多的运行良好的算法之一。
  • list 我的意思是抽象的数据结构。此时它们实际上存储在std::vector 中。

标签: c++ algorithm stl


【解决方案1】:

你可以试试std::merge,虽然这个算法一次只能合并两个排序的集合,所以你必须循环调用它。另请注意,std::list 提供 merge 作为成员函数。

编辑实际上std::inplace_merge 可能是一个更好的候选人。

【讨论】:

  • 运行时复杂度和这里的归并排序一样。 O(n * log(n))。子列表越少,您的运行时间就越好。只有 2 个子列表实际上是 O(n).
  • 我不能轻易地将数据分解成独立的列表来进行合并排序。我将不得不创建两个临时列表并一次去一个子集。我想我可以试试,列表的内存分配可能比低效排序更昂贵。
  • @edA-qa:您不必将它们分开。 std::merge 允许您指定开始和结束元素。如果你关心内存,你可能想看看std::inplace_merge
  • 你说得对。我首先查看了列表类中的“合并”。但独立功能确实采用任意序列。我必须将这种方式与 multiway_merge 进行比较。
  • 我什至不知道标准库中有inplace_merge这样的野兽!谢谢!
【解决方案2】:

这需要“多路合并”。标准库没有合适的算法。但是,GCC 标准库的并行扩展确实:

__gnu_parallel::multiway_merge.

【讨论】:

  • 这看起来我实际上可以让它在没有动态内存分配的情况下工作。谢谢!
  • 这是个坏主意,它不是标准的,可能会改变。如果可能的话,试着找一些更标准的东西。或者向 boost 提交功能请求。
  • 我更喜欢标准,但非标准不会打扰我。我已经在这部分代码中使用了几个 GCC 内置函数。
  • @the_drow:没有“标准”库函数可以做到这一点。此外,此 API不会更改。它是一个记录并发布的供公众使用的 API。此外,许可证实际上允许复制代码,因此该解决方案甚至可以在非 GCC 环境中使用(尽管这可能需要一些调整,这反过来意味着必须在 GPL 下发布更改,但运行时例外)。该解决方案远非完美,但使用多路合并是解决此问题的规范方法,这是我所知道的唯一可用且免费的实现。
【解决方案3】:

您可以一次迭代所有列表,为每个列表保留和索引。并仅比较该索引中的项目。

这可能比常规排序快得多:O(n) vs O(n*log(n)) 其中 n 是所有列表中的项目数。

请参阅wikipedia 文章。

C++ 有 std::merge ,但它不会同时处理多个列表,因此您可能需要制作自己的版本。

【讨论】:

  • 如果你做错了,你实际上会增加你的总比较。
  • 如果有很多子列表,这会发生故障。在拥有 n 个子列表的最坏情况下,运行时复杂度为 O(n²)
【解决方案4】:

如果你可以节省内存,mergesort 将在这方面表现得非常好。为获得最佳效果,请一次合并两个最小的链,直到只有一个。

【讨论】:

  • 合并的顺序真的重要吗?
  • 列表的大小越接近,每次合并所需的平均比较就越少。自下而上构建可为您提供最佳比较计数,而无需进行大量规划工作。您可以通过一些更复杂的计划来稍微提高缓存性能,但这真的不值得。
猜你喜欢
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-29
  • 1970-01-01
  • 2017-07-05
相关资源
最近更新 更多