【问题标题】:What sorting algorithm does list::sort use in msvc?list::sort 在 msvc 中使用什么排序算法?
【发布时间】:2019-04-25 15:10:32
【问题描述】:

据我所知,std::sort 通常使用 introsort。

但是,当我看这里的文章时,std::list::sort 说归并排序很容易实现,并没有提及使用哪种算法。

msvc 是否使用归并排序?

【问题讨论】:

  • 编写一个最小程序并使用调试器单步调试如何?
  • 我删除了与标题或主要问题无关的最后一个问题。无论如何:(特定实现和变体)合并排序作为通用排序机制在大多数语言中被广泛采用,因为它只是“在一般情况下运行良好”(它也是一种稳定的排序)。合并排序甚至与“introsort”一起使用。
  • "当我在这里看文章时" - 在哪里?
  • 实现在列表头,_Sort()函数。看一看。是的,vs2017 中的归并排序。

标签: c++ algorithm list sorting visual-c++


【解决方案1】:

该算法在 Visual Studio 2015 中从自下而上更改为自上而下合并排序。更改的作者表示这样做是为了处理没有默认分配器的列表,但使用 get_allocator() 可以轻松处理(修复将在声明列表时为列表数组中的 26 个元素中的每一个包含一个 get_allocator() 实例)。

更新 - Visual Studio 版本的关键变化是从使用列表数组切换到使用存储在堆栈中的迭代器并通过拼接进行合并,采用自上而下的方法。迭代器避免了没有默认分配器的问题。如果比较或其他问题引发异常,则通过拼接防止列表中的数据丢失。然而,事实证明,使用迭代器数组并通过拼接逻辑使用基本相同的合并的自下而上方法是可能的,尽管直到最近我才尝试实现基于迭代器的自下而上合并排序。下面第一个链接中的讨论现在包括使用迭代器的自下而上合并排序代码示例。

作者确实注意到切换到自上而下意味着性能下降,但正确指出如果性能是一个问题,那么在大多数情况下,将列表移动到向量,对向量进行排序,然后从排序后创建列表矢量会更快。尽管如此,大多数 STL 函数还是相当优化的,因此一些人的论点是,早期的自底向上方法可以修复为处理无默认分配器列表。

虽然作者没有提到这一点,但在下面链接的讨论中,也有人指出,如果用户比较函数抛出异常,自顶向下实现可以避免丢失数据。但是,如果比较函数抛出异常,其他 STL 函数(例如 std::stable_sort() 将丢失数据,我的印象是用户提供的函数创建的异常不是 VS STL 的优先级,应该在调试版本中捕获。

`std::list<>::sort()` - why the sudden switch to top-down strategy?

Wiki 文章包含链接列表的自上而下和自下而上合并排序的示例:

https://en.wikipedia.org/wiki/Merge_sort#Top-down_implementation_using_lists

https://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation_using_lists

【讨论】:

    【解决方案2】:

    在 Visual Studio 2017 中可以看到的 &lt;list&gt; 标头中,您将找到遵循合并排序的 _Sort 的函数模板。

    您还可以找到 merge 函数的多个重载和函数模板。

    【讨论】:

      猜你喜欢
      • 2014-05-18
      • 2010-12-15
      • 1970-01-01
      • 1970-01-01
      • 2012-11-01
      • 1970-01-01
      • 2014-07-29
      • 2021-10-28
      • 1970-01-01
      相关资源
      最近更新 更多