C++ while循环中带排序的列表stl的时间复杂度

C++ while循环中带排序的列表stl的时间复杂度,c++,stl,C++,Stl,以下代码的时间复杂度是多少: while(!list.empty()) { list.sort(); a = list.front(); list.pop_front(); b = list.front(); list.pop_front(); /** do something calculations*/ } list.sort()的每次调用都有O(N log N)复杂性1。对于排序列表,它可能会更快,但同样,它也可能会更慢(对于这种情况,标

以下代码的时间复杂度是多少:

while(!list.empty()) {
    list.sort();
    a = list.front();
    list.pop_front(); 
    b = list.front();
    list.pop_front();
    /** do something calculations*/
}

list.sort()
的每次调用都有O(N log N)复杂性1。对于排序列表,它可能会更快,但同样,它也可能会更慢(对于这种情况,标准不保证任何方向)。它通常被实现为一个合并排序,这通常不会受到预先存在的顺序的太大影响(如果有的话)

在本例中,您调用它O(N)次,因此您的总体复杂性为O(N2 logn)

正如注释中已经指出的,只要您只从列表的前面删除项目,列表将保持排序,因此无需在每次迭代时重新排序

此外,我注意到,如果只从一开始就删除元素,您可能需要考虑使用<代码> STD::DeQue/Cuth>而不是<代码> STD::List。尽管无论哪种方式,计算复杂度都是一样的,但您很有可能会看到现实生活中的速度从

列表
deque
的大幅提高。在您的情况下,您可能无法用
deque
替换
list
(例如,
deque
不能提供与
list
相同的迭代器稳定性),但在某些情况下可以这样做


  • 如果您在意,标准(§[list.ops]/32)中的精确措辞是:“复杂性:大约N个log N比较,其中
    N==size()

  • 值得考虑的是,切换到
    std::sort
    会牺牲一些保障<代码>标准::列表::排序保留所有迭代器和指向元素的指针/引用,因此对于某些应用程序,切换可能是不可能的。编辑:
    std::list
    的实际用例已经不多了,但根据我的经验,始终保留迭代器是大多数迭代器的基础。因此,这可能是一个障碍(如果
    std::list
    首先是正确的选择)。@FrançoisAndrieux:Yup——可能还取决于
    std::list.sort()
    是否稳定,在这种情况下,如果切换到
    deque
    ,则需要使用
    std::stable\u sort
    而不是
    std::sort
    。谢谢,我还在计算后将元素放入列表中,因此每次我都需要对其进行排序,以获得前2个最少的元素。有没有更好的方法通过另一个容器或逻辑来实现它?要能够添加任意元素,然后检索N个最大的(或最小的,取决于您选择的排序顺序),您可能需要一个优先级队列。即使有一个列表,如果只插入几个元素,按顺序插入它们可能比先插入然后排序要快。