Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么要使用STL sort()进行二次时间排序?_C++_Sorting_Stl_Quadratic - Fatal编程技术网

C++ 为什么要使用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*

我试图使用STL sort()函数,根据存储在地图中的值对对象向量进行排序。令我大吃一惊的是,我的算法是以二次时间运行的。我尽可能地简化了它,试图找出一个明显的错误,但没有用。以下是简化版本:

#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:Inside
a::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);
//                     ^^^^^