【发布时间】:2017-08-12 10:47:25
【问题描述】:
给定一个 C++ 向量(假设它是双精度的,我们称之为 unsorted),创建包含 unsorted 的排序副本的新向量 sorted 的最高效方法是什么?
考虑以下简单的解决方案:
std::vector<double> sorted = unsorted;
std::sort(sorted.begin(), sorted.end());
这个解决方案有两个步骤:
- 创建
unsorted的完整副本。 - 排序。
但是,在步骤 1 的初始副本中可能会浪费大量精力,尤其是对于(例如)已经大部分排序的大型向量。
如果我手动编写此代码,我可以将排序算法的第一遍与步骤 1 结合起来,通过让第一遍从 unsorted 向量中读取值,同时将它们写入 @ 987654328@。根据算法,后续步骤可能仅适用于 sorted 中的数据。
有没有办法用 C++ 标准库、Boost 或第三方跨平台库来做这样的事情?
重要的一点是确保sorted C++ 向量的内存在排序开始之前不会不必要地初始化为零。许多排序算法需要立即对sorted 向量进行随机写入访问,因此使用reserve() 和push_back() 不适用于第一次通过,但resize() 会浪费时间初始化向量。
编辑:由于答案和 cmets 不一定明白为什么“幼稚的解决方案”效率低下,因此请考虑 unsorted 数组实际上已经按排序顺序排列的情况(或者只是需要一个交换来排序)。在这种情况下,无论使用哪种排序算法,对于简单的解决方案,每个值都需要至少读取两次——一次是在复制时,一次是在排序时。但是使用排序时复制解决方案,读取次数可能会减半,因此性能大约会增加一倍。无论unsorted 中的数据如何,当使用比std::sort 性能更高的排序算法(可能是O(n) 而不是O(n log n))时,都会出现类似的情况。
【问题讨论】:
-
先复制,再排序。
std::vector有一个高效的复制方法。 -
在这种情况下,朴素的解决方案非常可靠。
-
以下链接不是通用算法,但值得一读。 probablydance.com/2016/12/27/i-wrote-a-faster-sorting-algorithm
-
如果在 STL 中添加一个
insertion_sort方法会很好,这样可以很好地完成这项任务。