在c++中,为什么要求列表在合并之前必须排序

In C++, why there is a requirement that lists must be sorted before merging

本文关键字:排序 合并 c++ 为什么 列表      更新时间:2023-10-16

在c++中,列表数据结构有一个merge函数,基本上就是把源列表中的所有对象都移到目标列表中。

// source list will be empty after this operation
destinationList.merge(sourceList);

根据教程/示例,在合并操作之前必须对列表进行排序。

destinationList.sort();
sourceList.sort();
destinationList.merge(sourceList);

我很困惑,因为如果有排序列表的要求,为什么c++不通过在合并函数中调用排序函数来强制执行它?

还有一件事,我可以先对未排序的列表进行归并,然后再对已排序的列表进行排序,这不是一样吗?

destinationList.merge(sourceList);
destinationList.sort();

为什么要求列表在合并之前必须排序?

merge的目的是合并两个排序列表以创建一个新的排序列表,而不需要执行另一个排序的开销。归并可以在线性时间内完成,而排序是O(n*log(n))

为什么c++不通过在merge函数中调用sort函数来强制执行?

因为,如果列表已经排序了,那将是非常低效的。

还有一件事,我可以先对未排序的列表进行归并,然后再对已排序的列表进行排序,这不是一样的吗?

。合并算法要求对输入进行排序,并从中产生一个排序列表。它的工作原理是比较输入列表的第一个元素,取较低的元素,并将其附加到输出列表中。

你可以通过添加两个列表然后对结果排序来实现同样的事情;但是,如果列表已经排序,那么这样做的效率会很低。

c++设计的驱动原则之一是"不要为你不用的东西买单"。

你可能指的是

的要求

§23.3.5.5 list操作

void merge(list& x);

void merge(list&& x);

template void merge(list& x, Compare comp);

template void merge(list&& x, Compare comp);

22 require: comp必须定义一个严格的弱排序(25.4),并且列表和实参列表都必须按照这个顺序排序。

在实际实现中发生的是,合并操作不只是取两个列表并将元素从一个复制到另一个,它只是利用某种链表结构的底层表示,并将元素从一个列表链接到另一个列表。它将遍历两个列表并取下一个更大的元素。因为这两个列表都已经排序过了,所以它可以通过总是查看两个列表的第一个元素来做到这一点。线性时间O(n)的运算。

如果你总是将它们连接起来(这是在常数时间内通过拼接操作实现的一种操作)然后对它们排序,那么复杂度将上升到O(n log n)。如果您已经有排序列表,则不希望这样做。

如果你没有,那么把它们拼接在一起,然后排序是你想要做的事情。

分别提供了所有这些功能(拼接、合并、排序),用户可以根据他对列表是否已经排序的了解,选择最有效的方式来组合列表。

如果你在这里指的是"合并"而不是"合并",那就略有不同了。

组合在一起之前,不要求对列表进行排序。根据你的需求,有3种不同的组合列表的方法

合并排序列表:

list1.merge( list2 ) // Complexity linear. Assumes list1 & list2 are sorted

将列表中的所有元素移动到另一个列表中:

list1.splice( std::end( list1 ), list2 ) //Complexity: constant

将一个列表中的一些元素复制到另一个列表中:

list1.insert( it1, it2 )// Complexity: linear, it1 & it2 are iterators pointing into list2

所以实际上c++标准提供了多种算法,每种算法都具有针对特定任务的最佳复杂度。