c++ - std::sort 可以专门使用 as-if 规则对 int* 使用冒泡排序吗?
问题描述
std::sort
有复杂度要求,即 O(n log n)。除了常见的 QuickSort 或 IntroSort,其他算法也适合它。
使用 O(n 2 )的冒泡排序肯定不适合。
但是,如果我们对int
没有显式谓词的指针进行专门化。无法观察迭代或比较的次数,因为没有办法专门化operator<
或指针间接,并且不允许用户的代码专门std::less
化int
s,并且由于谓词未传递,它是std::less
/ operator<
。
那么,int*
无谓词版本可以通过 STL 的一些邪恶实现来专门使用冒泡排序吗?
这个问题类似于使用基数排序实现 std::sort 的重载是否合法?,但答案指出Radix排序符合要求,所以不是我打算问的。
实际意图是如果允许实现进行优化,这对复杂性来说更糟,但对运行时更好。我想专注于“如果允许这样做”而不是“如果这可能以更复杂的复杂性更快地实现”,这就是为什么我选择冒泡排序作为明显可怕的例子。
解决方案
无法观察到迭代或比较的次数
所以?算法的复杂性由标准给出,而不是某些观察者。你是否能观察到这种复杂性是无关紧要的。
- 复杂性:让 N 排在最后 - 首先。O(NlogN) 比较和预测。
这很清楚。另一方面,冒泡排序需要 O(n^2),因此如果一个实现要使用冒泡排序,它将不符合标准。
我根本看不出假设规则是如何相关的。
另请注意,自定义仿函数存在重载Compare
,在这种情况下,可以观察到比较的数量,即使对于原始类型也是如此。
实际意图是如果允许实现进行优化,这对复杂性来说更糟,但对运行时更好。
std::sort
不,正如我上面所说,上限很明确。但是如果通过某种魔法,编译器可以排序O(1)
或不使用Compare
,它一定可以做到这一点。如果编译器可以证明你无法观察到是否std::sort
已经被调用,那么 as-if 规则就可以在这里发挥作用。非常理论上,如果您std::sort
只使用查找和访问最小元素,则编译器在此规则下允许使用简单的 for 循环查找最大值。
推荐阅读
- c# - 为什么 CertificateRequest.Create 有时会在序列号中添加前导零字节?
- scala - 如何在spark scala中截断数据框中多行和多列的值
- python - 如何为部署在 Heroku 上的电报机器人编写定期重复的函数
- r - coef() 函数和调试消息
- heroku - 表格中的虚拟行
- r - 不知道为什么 eigen() 给出了一个错误符号的向量,而加载矩阵只是向量
- javascript - 声明时 const 存储在哪里?
- mysql - mysql 5.6 的自定义 json_extract 函数无法按预期工作
- c# - 改变弹丸角度
- html - 未应用角度中 ng5-slider 的样式