我在C ++中找到了两种形式的sort():
1)排序(开始,结束);
2)XXX.sort();
可以在没有对象的情况下直接使用,也可以使用对象。
这就是全部吗?这两种排序()之间有什么区别?他们来自同一个图书馆?第二个是XXX的方法吗?
我可以像这样使用它吗
vector<int> myvector
myvector.sort();
或
list<int> mylist;
mylist.sort();
答案 0 :(得分:16)
std::sort
是一个函数模板,可与任何一对随机访问迭代器一起使用。因此,由std::sort
实现的算法被定制(优化)用于随机访问。大多数时候它会有一些快速排序的风格。
std::list::sort
是一个专门的面向列表的排序版本。 std::list
是一个不支持[高效]随机访问的容器,这意味着您无法使用std::sort
。这产生了对专用排序算法的需求。大多数情况下,它将被实现为一些合并排序的风格。
答案 1 :(得分:2)
std::list
包含sort()
成员,因为有些方法可以有效地对列表进行排序,但几乎没有别的。如果您尝试对列表使用相同的排序实现,则其中一个不能很好地工作,因此它们为list
提供了一个特殊的排序。
大多数情况下,您应该使用std::sort
,并忘记std::list
甚至存在。它在一些非常具体的情况下是有用的,但它们是非常罕见的,使用它是一个错误,至少90%的时间是人们认为应该的。
编辑:情况并非使用std::list::sort
是错误的,但使用std::list
通常是错误的。这有几个原因。首先,std::list
除了存储每个项目的空间外还需要几个指针,因此除非您的数据相当大,否则可能会产生大量的空间开销。其次,由于每个节点都是单独分配的,因此遍历节点往往相当慢(引用的位置较低,因此缓存利用率往往较差)。最后,虽然您可以从列表中间插入或删除具有常量复杂性的元素,但您(通常)需要使用列表的线性复杂性遍历来找到插入或删除该项的正确点。结合缓存利用率较低的情况,在链表中间进行插入和删除通常较慢而不是像vector或deque那样。
其他10%的时间(或者可能稍微少于一点)是您可以长期合理存储列表中的位置,并且(至少通常)计划制作在同一点(接近)处进行多次插入和删除,每次都不遍历链表以找到正确的位置。如果您在同一位置(或接近)对列表进行足够的修改,则可以通过多次插入和删除来分摊列表遍历。如果你在同一个地方(接近)做了足够的修改,那么可以提前出现。
在少数情况下可以很好地解决这个问题,但是会迫使您长期存储更多“状态”数据,主要是为了弥补数据结构本身的不足。在可能的范围内,我更倾向于使单个操作接近纯粹和原子,因此它们最小化对长期数据的依赖性(和影响)。在单线程情况下,这主要有助于模块化,但是对于多核,多线程(等)编程,它还可以对效率和开发难度产生实质性影响。访问该长期数据通常需要线程同步。
这并不是说避免列表会自动使你的程序更快,或类似的东西 - 只是我发现非常罕见的情况非常有用,并且很多情况似乎以适应人们被告知的链接列表何时有用,实际上并非如此。
答案 2 :(得分:0)
std::sort
仅适用于随机访问迭代器。这将它限制为数组,向量和双端队列(以及提供随机访问的用户定义类型)。
std::list
是一个不支持随机访问的链表。通用排序功能不适用于它。即使它确实如此,也不是最理想的。链接列表不是通过从节点复制数据来排序的 - 它通过重新链接节点进行排序。
std::sort
也不适用于其他容器(集合和映射),但总是会对它们进行排序。