简体   繁体   English

使用std :: sort稳定对向量进行排序

[英]Stable sorting a vector using std::sort

So I have some code like this, I want to sort the vector based on id and put the last overridden element first: 所以我有这样的代码,我想根据id对向量进行排序,然后将最后一个覆盖的元素放在第一位:

struct Data {
  int64_t id;
  double value;
};
std::vector<Data> v;

// add some Datas to v
// add some 'override' Datas with duplicated `id`s

std::sort(v.begin(), v.end(),
  [](const Data& a, const Data& b) {
    if (a.id < b.id) {
      return true;
    } else if (b.id < a.id) {
      return false;
    }
    return &a > &b;
});

Since vectors are contiguous, &a > &b should work to put the appended overrides first in the sorted vector, which should be equivalent to using std::stable_sort , but I am not sure if there is a state in the std::sort implementation where the equal values would be swapped such that the address of an element that appeared later in the original vector is earlier now. 由于向量是连续的,因此&a > &b应该可以将附加的替代项首先放在已排序的向量中,这等效于使用std::stable_sort ,但是我不确定std::sort实现中是否存在状态,其中相等的值将被交换,以使出现在原始向量后面的元素的地址现在更早。 I don't want to use stable_sort because it is significantly slower for my use case. 我不想使用stable_sort因为对于我的用例而言,它的速度明显慢。 I have also considered adding a field to the struct that keeps track of the original index, but I will need to copy the vector for that. 我还考虑过在结构中添加一个字段,以跟踪原始索引,但是我需要为此复制向量。

It seems to work here: https://onlinegdb.com/Hk8z1giqX 似乎在这里工作: https : //onlinegdb.com/Hk8z1giqX

std::sort gives no guarantees whatsoever on when elements are compared, and in practice, I strongly suspect most implementations will misbehave for your comparator. std::sort在比较元素时不提供任何保证,在实践中,我强烈怀疑大多数实现都会对您的比较器产生不良影响。

The common std::sort implementation is either plain quicksort or a hybrid sort (quicksort switching to a different sort for small ranges), implemented in-place to avoid using extra memory. 常见的std::sort实现是普通的快速排序或混合排序(对于小范围,快速排序切换到其他排序),它们是就地实现的,以避免使用额外的内存。 As such, the comparator will be invoked with the same element at different memory addresses as the sort progresses; 这样,随着排序的进行,比较器将在不同的存储器地址处使用相同的元素来调用; you can't use memory addresses to implement a stable sort. 您不能使用内存地址来实现稳定的排序。

Either add the necessary info to make the sort innately stable (eg the suggested initial index value) or use std::stable_sort . 添加必要的信息以使排序固有稳定(例如,建议的初始索引值),或使用std::stable_sort Using memory addresses to stabilize the sort won't work. 使用内存地址来稳定排序将不起作用。

For the record, having experimented a bit, I suspect your test case is too small to trigger the issue. 作为记录,经过一些试验,我怀疑您的测试用例太小而无法触发问题。 At a guess, the hybrid sorting strategy works coincidentally for smallish vector s, but breaks down when the vector gets large enough for an actual quicksort to occur. 猜测一下,混合排序策略对较小的vector s会同时起作用,但是在vector量变大到足以发生实际的快速排序时分解。 Once I increase your vector size with some more filler, the stability disappears, Try it online! 一旦添加更多填充物来增加vector大小,稳定性就会消失, 请在线尝试!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM