C++ std::list.sort()的奇怪效率
好的,下面是: 我想使用一个双链接列表并对其中的对象进行排序。这些对象属于另一个类。奇怪的是:当我使用我自己创建的双链接列表时,我会在将元素添加到列表中时对它们进行排序。这类似于插入排序,因此效率为n^2 但这比使用std::list排序要快得多,在这种排序中,我将所有元素添加到列表中,然后调用sort()。我真的不明白为什么 更多信息:目前我对~500个元素进行排序 我是不是把清单弄错了 编辑:一些代码 std::list的代码C++ std::list.sort()的奇怪效率,c++,list,sorting,stl,linked-list,C++,List,Sorting,Stl,Linked List,好的,下面是: 我想使用一个双链接列表并对其中的对象进行排序。这些对象属于另一个类。奇怪的是:当我使用我自己创建的双链接列表时,我会在将元素添加到列表中时对它们进行排序。这类似于插入排序,因此效率为n^2 但这比使用std::list排序要快得多,在这种排序中,我将所有元素添加到列表中,然后调用sort()。我真的不明白为什么 更多信息:目前我对~500个元素进行排序 我是不是把清单弄错了 编辑:一些代码 std::list的代码 for every object: list.push_
for every object:
list.push_back(object);
list.sort();
我的名单:
struct node{
someObject* data;
float depth;
node* prev;
node* next;
node(someObject* o){
data = o;
prev = NULL;
next = NULL;
depth = depthFunc(o);
}
float depthFunc(someObject* o);
};
struct myList{
node* head;
node* tail;
void insertAfter(node* toAdd, node* n);
void insertBefore(node* toAdd, node* n);
void addNode(someObject* o){
node* n = new node(o);
if (head == NULL) {
head = n;
tail = n;
} else {
node* temp = head;
while(temp != NULL && temp->depth < n->depth){
temp = temp->next;
}
if (temp != NULL) insertBefore(n, temp);
else insertAfter(n, tail);
}
}
};
struct节点{
someObject*数据;
漂浮深度;
节点*prev;
节点*下一步;
节点(someObject*o){
数据=o;
prev=NULL;
next=NULL;
深度=深度函数(o);
}
float depthFunc(someObject*o);
};
结构myList{
节点*头;
节点*尾部;
void insertAfter(节点*toAdd,节点*n);
void insertBefore(节点*toAdd,节点*n);
void addNode(someObject*o){
节点*n=新节点(o);
if(head==NULL){
水头=n;
尾=n;
}否则{
节点*温度=头部;
while(temp!=NULL&&temp->depthdepth){
温度=温度->下一步;
}
如果(temp!=NULL)insertBefore(n,temp);
else-insertAfter(n,tail);
}
}
};
手写排序函数的时间复杂度为O(N^2
)。每个元素都被插入(调用addNode
n
次),需要n
操作才能找到插入点(给出n*n=n^2
)
std::list::sort()
要求具有O(n lg n
)复杂性,这比O(n^2
)要快得多。(lgn
的增长速度比n
慢得多)
手写排序是的一种变体
请注意,对于大多数输入,使用std::vector
和std::sort
而不是std::list
和std::list::sort
将获得更快的结果
如果您的问题是“为什么手写版本更快?”,这取决于您的输入。对于某些输入,插入排序可以是
O(n)
。(对于您的实现,当元素以相反的顺序插入时会发生这种情况)我猜您的n^2是最糟糕的情况复杂性,如果您幸运的话,根据数据(预排序),它可能会更好。您是如何衡量这一点的?请提供一个列表,并在生成时插入列表元素具有O(n log n)
比较,因为双向迭代器上的std::binary\u search
会进行O(logn)
比较(您仍然有O(N^2)
迭代器增量,但它们通常比比较便宜得多)。std::list::sort
同样具有O(N logn)
复杂性(比较计数)。因此,除非您提供更多的代码,否则我们只能猜测是什么解释了您的结果。添加了一些简单的代码:“但这比使用std::list排序要快得多,在std::list排序中,我将所有元素添加到列表中,然后调用sort()。我真的不明白为什么……”@DyP:Hmm。。我明白你的意思。这个问题有点让人困惑,它是说std::list
版本更快(即“为什么我的手写代码没有更快?”)还是手写版本更快(即“为什么手写版本更快?”)