由于标准库集合容器中的项目已经排序,因此使用集合中的查找成员通常比在排序列表中对相同项目使用查找算法执行速度更快吗?
由于列表是线性的,并且通常使用排序树来实现集合,因此似乎set-find应该更快。
答案 0 :(得分:6)
使用链接列表,即使是已排序的列表,查找元素也是O(n)
。可以在O(log n)
中搜索一个集合。因此,在集合中查找元素渐近更快。
可以使用二进制搜索在O(log n)
中搜索已排序的数组/向量。遗憾的是,由于链接列表不支持随机访问,因此不能使用相同的方法在O(log n)
中搜索已排序的链接列表。
答案 1 :(得分:1)
它实际上在标准中:std::set::find()
具有复杂性O(log n)
,其中n
是集合中元素的数量。另一方面,std::find()
在搜索范围的长度上是线性的。
如果您的通用搜索范围发生要进行排序并具有随机访问权限(例如已排序的向量),那么您可以使用std::lower_bound()
有效地查找元素(或更确切地说是位置)
请注意,std::set
附带了自己的成员 - lower_bound()
,其工作方式相同。即使在set
中,插入位置也很有用,因为带有正确提示的insert()
具有复杂性O(1)
。
答案 2 :(得分:0)
您通常可以期望find
上的Set
操作比List
更快,因为列表是线性访问(O(n)),而集合可能接近{{1}} -shstant访问HashSets(O(1)),或对TreeSet的对数访问(O(log n))。
答案 3 :(得分:0)
set::find
的复杂度为O(log(n)),而std::find
的复杂度为O(n)。这意味着std::set::find()
渐近比std::find(std::list)
更快,但这并不意味着它对任何特定数据集或任何特定搜索都更快。
答案 4 :(得分:0)
我发现这篇文章对这个主题很有帮助。 http://lafstern.org/matt/col1.pdf
您可以重新考虑您对“列表”与“集合”的要求。根据那篇文章,如果你的程序在开始时主要包含一堆插入,然后在那之后,只与你存储的内容进行比较,那么你最好将所有内容添加到一个向量中,使用std :: sort( vector.begin(),vector.end())一次,然后使用lower_bound。在我的特定应用程序中,我在程序启动时从文本文件加载一个名称列表,然后在程序执行期间我确定用户是否在该列表中。如果他们是,我做一些事情,否则,我什么都不做。换句话说,我有一个单独的离散插入阶段,然后我排序,然后我使用std :: binary_search(vector.begin(),vector.end(),std :: string username)来确定用户是否是在列表中。