C++ 为什么要使用STL sort()进行二次时间排序?
我试图使用STL sort()函数,根据存储在地图中的值对对象向量进行排序。令我大吃一惊的是,我的算法是以二次时间运行的。我尽可能地简化了它,试图找出一个明显的错误,但没有用。以下是简化版本:C++ 为什么要使用STL sort()进行二次时间排序?,c++,sorting,stl,quadratic,C++,Sorting,Stl,Quadratic,我试图使用STL sort()函数,根据存储在地图中的值对对象向量进行排序。令我大吃一惊的是,我的算法是以二次时间运行的。我尽可能地简化了它,试图找出一个明显的错误,但没有用。以下是简化版本: #include <map> #include <vector> #include <algorithm> using namespace std; struct a{ map<a*,float> vals; bool operator()(a*
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
struct a{
map<a*,float> vals;
bool operator()(a* a1, a* a2){return (vals[a1]>vals[a2]);}
void asort();
};
void a::asort(){
vector<a*> v;
map<a*,float>::iterator it = vals.begin();
for(;it!=vals.end();it++){v.push_back((*it).first);}
sort(v.begin(),v.end(),*this);
}
int main(){
a a0;
int imax=8000;
for(int i=0;i<imax;i++){a0.vals[new a]=rand();}
a0.asort();
}
#包括
#包括
#包括
使用名称空间std;
结构a{
地图VAL;
布尔运算符()(a*a1,a*a2){return(vals[a1]>vals[a2]);}
void asort();
};
void a::asort(){
向量v;
map::iterator it=vals.begin();
对于(;it!=vals.end();it++){v.push_back((*it.first);}
排序(v.begin(),v.end(),*this);
}
int main(){
a0;
int imax=8000;
对于(int i=0;i一个映射已经排序。std::sort
可能基于快速排序,其最坏的性能是当输入预先排序时。按值获取其谓词,即
将复制包含的映射
接下来,您将在比较期间执行两次映射查找,即O(logn)
,而pred(a,b)
是一个常量操作
您可以通过为std::sort
定义一个单独的比较器,并使用std::unordered\u map
(C++11)来解决这个问题。您确定时间是由排序而不是其他计算消耗的吗?您真的需要在映射上调用sort(它已经排序了)@FamZheng:没有其他的计算,时间是为你的代码计算的see@Rick:代码没有对映射进行排序,而是基于指针映射到的浮点值的指针向量。@Rick:我需要按映射值排序。它是如何排序的?我不明白。你的意思是我可以在不使用sort()的情况下得到向量v吗?向量根据a*
映射到的浮点进行排序。此外,通常使用introsort(一种根据输入进行调整的算法)来实现。std::sort更复杂,它是插入排序/快速排序IIRC的组合(您只需查看)。但您可能认为会有一个简单返回的map重载…@Rick,这将取决于具体的实现。问题没有提到编译器。不,没有,但您可以查看您的发行版,这是我的观点(很抱歉不清楚)@Xeo,这是针对平均情况还是最坏情况的规范?@Mark:Insidea::operator()
,当从a*
映射到float
时,您会得到映射查找。而O(n)
如何支持较长的输入?vals.size()==n
在OP的代码中,这意味着复制和查找的时间更长。你的意思是我从复制地图中获得了额外的n因子吗?为什么每次比较都会创建地图的副本?对不起,我不明白为什么得到~O(n^2)@Flash:看一下我答案中的std::sort
链接。第三个参数是compra
,它将复制作为第三个参数传递的任何内容。在本例中,即*this
,它包含一个大小等于imax
的映射,因此会导致O(imax)
复制:我同意至少复制第三个参数一次。但是,如果我理解正确,O(imax^2)只能由每次比较花费额外的O(imax)因子产生。为什么每次都复制映射?@FlashCards:记住,您在操作符()
中进行映射查找,这会添加O(log imax)
。此外,您的函数似乎不是完全二次函数。
sort(v.begin(),v.end(),*this);
// ^^^^^