要求排序区间的算法有:
- binary_search
- lower_bound
- upper_bound
- equal_range
- set_union
- set_interation
- set_difference
- set_symmertric_difference
- merge
- inplace_merge
- includes
- unique
- unique_copy
binary_search、lower_bound、upper_bound、equal_range要求排序的区间,因为他们用二分法查找数据。这些算法承诺了对数时间的查找效率,但前提条件是,你必须提供已经按顺序排好的数据。
实际上,这些算法并不一定保证对数时间的查找效率。只有当它们接受了随机访问迭代器的时候,它们才保证有这样的效率。如果所提供的迭代器不具备随机访问的能力,那么,尽管比较次数依然是区间元素个数的对数,但它们的执行过程却需要线性时间。这是因为,由于缺少了执行‘迭代器算术’的能力,所以在查找过程中它们需要线性时间以便从区间的一处移动到另外一处。
set_union、set_interseciont、set_difference、set_symmetric_difference提供了线性时间效率的集合操作,它们的名字暗示了每个算法要完成的操作。为什么它们需要排序的区间呢?因为如果不满足这个条件,它们就无法在线性时间内完成工作。
merge、inplace_merge实际上实现了合并和排序的联合操作:它们读入两个排序的区间,然后合并成一个新的排序区间,其中包含了原来两个区间中的所有元素。它们具有线性时间的性能。但如果它们不知道源区间已经排过序的话,它们就不可能在线性时间内完成。
includes用来判断一个区间中的所有对象是否都在另外的一个区间中。因为includes总是假设这两个区间是排序的。所有承诺线性时间的效率。如果没有这一前提,它通常会运行更慢。
unique和unique_copy并不要求排序的区间,但通常会与排序区间一起使用。
unique为什么需要排序,看下C++标准对其的描述:
Eliminate all but the first element from every consecutive groups of equal elements
如果不排序,你就无法使容器中的元素唯一。
要求排序区间的算法会所以有这样的要求是为了提供更好的性能,而对于未排序的区间他们无法保证有这样的性能。
所有要求排序区间的算法均使用等价性来判断两个对象是否“相同”,这与标准的关联容器一致。于此相反的是,unique和unique_copy在默认情况下使用“相等”来判断两个对象是否“相同”,当然你可以改变这种默认行为,只需要给这些算法传递一个其他的预定义比较函数作为两个值“相同”的定义即可。
这11个算法之所以要求排序的区间,目的是为了提供更好的性能。只要确保提供给它们排序的区间,并保证这些算法所使用的比较函数与排序所使用的比较函数一致,你就可以有效地使用这些与查找、集合操作几区间合并有关的算法,并且你会发现,unique和unique_copy如愿地删除了所有重复的值。