提问者:小点点

对数字及其索引列表进行排序的最快方法


我有一个看起来很基本的问题,但它是在一个“每一个CPU滴答计数”(这是将在超级计算机上使用的更大算法的一部分)的上下文中提出的。

问题很简单:对一个由无符号长int数及其原始索引组成的列表进行排序的最快方法是什么?(在开始时,无符号的long long int数是完全随机排列的。)

Example :
Before
Numbers: 32 91 11 72
Indexes: 0 1 2 3
After
Numbers: 11 32 72 91
Indexes: 2 0 3 1 

所谓“最快的方式”,我的意思是:使用什么算法:std::sort,C qsort,还是web上可用的另一种排序算法?要使用的容器(C数组,std::Vector,std::Map...)?如何同时对索引进行排序(使用结构,std::pair,std::map...)?

要排序多少元素?-&>;通常是4GO的数字


共3个答案

匿名用户

显而易见的起点是定义了的结构:

struct data { 
    unsigned long long int number;
    size_t index;
};

struct by_number { 
    bool operator()(data const &left, data const &right) { 
        return left.number < right.number;
    }
};

。。。和保存数据的std::vector:

 std::vector<data> items;

执行排序:

 std::sort(items.begin(), items.end(), by_number());

简单的事实是,普通的容器(以及类似的容器)足够有效,使用它们并不会使代码的效率大大降低。你也许可以通过用不同的方式写一些部分来做得更好,但你也可能很容易做得更差。从可靠的,可读的开始,并进行测试--不要(试图)过早地优化。

编辑:当然,在C++11中,您可以使用lambda表达式来代替:

std::sort(items.begin(), items.end(), 
          [](data const &a, data const &b) { return a.number < b.number; });

这样写起来一般会方便一点。可读性取决于--对于像这样简单的东西,我认为是非常可读性的,但这(很大程度上)取决于您给比较运算符起的名字。lambda使实际的排序条件更容易找到,因此您不需要为代码的可读性而仔细选择名称。

匿名用户

非常适合您的要求:如果将值放入中的索引,您只需在,如下所示:

// This is your original data. It does not need to be in a vector
vector<long> orig;
orig.push_back(10);
orig.push_back(3);
orig.push_back(6);
orig.push_back(11);
orig.push_back(2);
orig.push_back(19);
orig.push_back(7);
// This is a vector of {value,index} pairs
vector<pair<long,size_t> > vp;
vp.reserve(orig.size());
for (size_t i = 0 ; i != orig.size() ; i++) {
    vp.push_back(make_pair(orig[i], i));
}
// Sorting will put lower values ahead of larger ones,
// resolving ties using the original index
sort(vp.begin(), vp.end());
for (size_t i = 0 ; i != vp.size() ; i++) {
    cout << vp[i].first << " " << vp[i].second << endl;
}

匿名用户

事实证明比旧的更快,因为缺少间接性,并且可以内联关键操作。

的实现可能是高度优化的,很难被击败,但并非不可能。如果您的数据是固定长度和短的,您可能会发现基数排序更快。Timsort相对较新,已经为Python提供了良好的结果。

您可以将索引数组与值数组分开,但我认为额外的间接级别将证明是速度杀手。最好将它们放在一个结构或中。

与任何速度关键应用程序一样,您必须尝试一些实际的实现,并对它们进行比较,以确定哪种实现速度最快。