【问题标题】:Strange efficiency of std::list.sort() [closed]std::list.sort() 的奇怪效率 [关闭]
【发布时间】:2013-04-22 17:29:52
【问题描述】:

好的,下面是:

我想使用一个双链表并想对其中的对象进行排序。对象属于另一类。奇怪的是:当我使用自己创建的双链表时,我在将元素添加到列表的那一刻对它们进行排序。这就像插入排序,所以效率为 n^2。

但这比使用 std::list 排序要快得多,在 std::list 排序中,我将所有元素添加到列表中,然后调用 sort() 。我真的不明白为什么......

更多信息:在我排序〜500个元素的那一刻。

我对列表做错了吗?

编辑:一些代码

std::list 的代码

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);
        }
    }
};

【问题讨论】:

  • 我猜你的 n^2 是最坏情况下的复杂度,如果幸运的话,根据数据(预排序)可能会更好
  • 你如何衡量这个?
  • 请提供SSCCE
  • 并且在生成列表元素时插入它们有 O(N log N) 比较,因为双向迭代器上的 std::binary_searchO(log N) 比较(你仍然有 O(N^2) 迭代器增量,但它们通常很多比比较便宜)。 std::list::sort 同样具有 O(N log N) 复杂性(比较计数)。因此,除非您向我们提供更多代码,否则我们只能猜测是什么解释了您的结果。
  • 添加了一些简单的代码

标签: c++ list sorting stl linked-list


【解决方案1】:

您的手写排序函数具有 O(N^2) 时间复杂度。每个元素都被插入(你调用addNoden 次),你需要n 操作来找到插入点(给n * n = n^2)。

std::list&lt;T&gt;::sort() 需要 O(n lg n) 复杂度,这比 O(N^2) 快得多。 (lg n 的增长速度比 n 慢得多)

您的手写排序是insertion sort 的变体。

请注意,对于大多数输入,使用 std::vectorstd::sort 代替 std::liststd::list::sort 会产生更快的结果。


如果您的问题是“为什么手写版本更快?”,这取决于您的输入。对于某些输入,插入排序可以是O(n)。 (对于您的实现,当元素以相反的顺序插入时会发生这种情况)

【讨论】:

  • OP:“但这比使用 std::list 排序要快得多,在 std::list 排序中,我将所有元素添加到列表中,然后调用 sort()。我真的不明白为什么。 ... "
  • @DyP:嗯……我明白你的意思。这个问题有点令人困惑,它是说std::list 版本更快(即“为什么我的手写代码没有更快?”)还是手写版本更快(即“为什么手写版本更快?” )
猜你喜欢
  • 2017-02-17
  • 1970-01-01
  • 2014-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-29
  • 2012-11-03
  • 2010-09-20
相关资源
最近更新 更多