【问题标题】:what's the difference between list.sort and std::sort?list.sort 和 std::sort 有什么区别?
【发布时间】:2011-11-05 00:20:40
【问题描述】:

我正在尝试使用 clang 编译以下代码,但出现以下错误。

我想知道为什么使用 list 类中的 sort 会起作用,而不是 std::sort

#include <list>
#include <iostream>

int main(){
    std::string strings[] = {"hello", "nihao", "byebye", "yo"};
    std::list<std::string> cars(strings, strings+sizeof(strings) / sizeof(char **));

    // cars.sort(std::less<std::string>()); // compiles fine and produce a sorted list

    std::sort(cars.rbegin(), cars.rend(), std::less<std::string>() ); // this one won't compile

    for (std::list<std::string>::iterator it = cars.begin(); it != cars.end(); ++it)
        std::cout << *it << " - ";

    std::cout << std::endl;
    return 0;
}

/usr/include/c++/4.2.1/bits/stl_iterator.h:320:25:错误:无效 二进制表达式的操作数('iterator_type'(又名 'std::_List_iterator >') 和 'iterator_type') { 返回 __y.base() - __x.base(); }

【问题讨论】:

标签: c++ algorithm templates std


【解决方案1】:

std::sort 需要 随机访问 迭代器,std::list 不提供。因此,std::liststd::forward_list 实现了它们自己的用于排序的成员函数,这些函数与它们较弱的迭代器一起工作。 这些成员函数的复杂性保证比那些更有效的通用算法更差。[哎呀:见 cmets。]

此外,成员函数可以通过简单地重新链接列表节点来利用列表数据结构的特殊性质,而标准算法必须执行类似swap(或类似的东西),这需要对象构造、赋值和删除。

注意remove() 是类似的情况:标准算法只是一些返回迭代器的重新排列,而list 成员函数一次性完成查找和实际删除;再次感谢能够利用列表内部结构的知识。

【讨论】:

  • 复杂性保证并不差。成员函数是“大约 N log N 比较”,而算法是“O(N log N) 比较”。考虑到成员函数将使用归并排序,这正如您所期望的那样,std::sort 可能会使用某种引入排序,然后退回到堆排序。
  • @Steve:啊,确实是我的一个彻头彻尾的误解。标准确实说列表函数使用 N log N 比较,而标准算法是“O(N log N)”。相同的渐近线,但我认为列表版本的常量更差。
  • 也许常量更糟,但请记住,标准复杂度保证只关心比较次数,而比较合并/快速/堆排序时的主要性能因素之一是引用的局部性。因此,应用于比较部分的常量不一定是主要的性能问题。我不知道堆排序的最坏情况比较次数是多于还是少于 N log N,但 N log N 是合并排序的最坏情况。当然,introsort 的预期情况总体上比 heapsort 的预期情况更快。
  • 合并排序也执行大约 N log N 迭代器增量操作(事实上,它每次比较都会执行一个增量,原因很简单),这很好,尽管位置完全取决于列表的方式构造和变幻莫测的分配器。归并排序对链表如此出色的原因在于它不需要额外的内存,而归并数组则需要。与任何排序算法一样,要感受它在一副纸牌上手动执行它 - 你不会觉得你缺少随机访问迭代器:-)
  • 哎呀,等一下,我只想到实际的合并,抱歉,2*k 递增以合并两个大小为k 的块。将数据分成“两半”需要一些额外的增量。是的,当元素很大时,重新链接节点会有所帮助。观察 insertion sort,对插入点进行二分搜索,只需要 O(N log N) 次比较,元素复制才是杀手锏 ;-)
猜你喜欢
  • 2014-07-22
  • 2017-03-19
  • 2014-04-21
  • 2012-05-08
  • 1970-01-01
  • 2023-04-09
  • 2020-10-16
  • 2020-09-30
  • 2021-10-16
相关资源
最近更新 更多