正在添加到集合 O(n)
Is adding to a set O(n)?
既然集合只能有唯一的值,这是否意味着每次将元素添加到集合时,它都必须检查它是否等于那里的每个元素,因此是O(n)?
如果是这种情况,这将使它们比 arrayLists 慢得多,因此您唯一应该实际使用它们的时间是确保您的元素都是唯一的还是它们还有其他优点?
这取决于set
的实现。
C++
C++中的std::set
通常实现为红黑树,并保证插入复杂度为 O(log(n))(源)。
std::set 是一个关联容器,其中包含一组排序的 Key 类型的唯一对象。排序是使用键比较功能比较完成的。搜索、删除和插入操作具有对数复杂性。
C++11的std::unordered_set
的插入复杂度为O(1)(来源)。
无序集是一个关联容器,其中包含 Key 类型的唯一对象集。搜索、插入和删除具有平均恒定时间复杂度。
.JAVA
在 Java 中,向HashSet
添加元素是 O(1)。从文档中:
此类为基本操作(添加、删除、包含和大小)提供恒定的时间性能,假设哈希函数在存储桶中正确分散元素
将元素插入TreeSet
是 O(log(n))。
此实现为基本操作(添加、删除和包含)提供有保证的 log(n) 时间成本。
所有实现Set
的类都可以在文档中找到。
结论
在大多数情况下,添加到set
并不比添加到ArrayList
或std::vector
慢。但是,set
不一定按插入顺序保留项目。此外,访问集合的第 N 个元素比对 ArrayList
或std::vector
的相同操作更复杂。每种方法都有其优点和缺点,应相应地使用。
你标记了这个 Java 和C++,所以我会回答这两个问题:
在C++ std::set
中是一个有序的容器,可能实现为树。无论实现如何添加到集合并检查集合中的元素是否保证为 O(log n)。对于 C++11 中新增的 std::unordered_set
,这些操作是 O(1)(给定适当的哈希函数)。
在Java中,java.util.Set
是一个接口,可以有许多不同的类来实现它们。操作的复杂性取决于这些类。最常用的集合是 TreeSet
和 HashSet
。前者的运算是O(log n),后者的运算是O(1)(再次给出适当的哈希函数)。
C++ std::set
通常实现为黑红树。这意味着添加到它将是 O(log n)。
C++ std::unordered_set
插入作为哈希表实现,因此插入为 O(1)。
您忘记了集合可能不是元素的批量列表; 它可以以搜索比O(N)
快得多的方式排列(确实如此)。
http://en.wikipedia.org/wiki/Set_(abstract_data_type)#Implementations
这取决于。不同的语言提供不同的实现。甚至Java也有2个不同的集合:TreeSet和HashSet。添加是树集是O(logn),因为元素已经按顺序排列。
在 CPP 中,集合通常实现为二叉搜索树。 话虽如此,插入将需要 O(log(N)) 时间复杂度。 当涉及到唯一键时,您可以尝试在 CPP 中hash_map,它在插入时具有恒定的时间复杂度。
时间复杂度:包装类与基元。
- 当值更改时,尤其是多次更改时,基元会提供更好的时间。
例:
int counter = 0;
while (x>y){
counter++;
}
比以下速度快得多:
Integer counter = 0;
while (x>y){
counter++;
}
- 当值保持不变时,包装类会提供更好的时间,因为只有指向包装类的指针传递给算法。它在定义不更改其值的方法的参数时非常方便。
例:
public int sum (Integer one, Integer two, Integer three){
int sum = one+two+three;
return sum;
}
比
public int sum (int one, int two, int three){
int sum = one+two+three;
return sum;
}
传递给方法的值可能是原始的,重要的是方法本身参数的定义,也就是说:
public int sum (Integer one, Integer two, Integer three){
int sum = one+two+three;
return sum;
}
int a = 1; int b = 2; int c = 3;
public int sum (a, b, c){
int sum = a+b+c;
return sum;
}
如上所述使用包装类的累积效应可以显著提高程序的性能。
正如其他人所说,集合通常是树O(logn)或哈希表O(1)。但是,有一件事您可以确定:任何健全的映射实现都不会具有 O(n) 行为。
- 将集合的随机元素添加到列表中,然后将其从原始集合中移除
- 将字符串集合中的元素添加到字符串集合的向量中
- 如何将不同的对添加到集合中?
- 如何添加到已存储在集合中的集合
- 嗨,我正在尝试将集合的特定节点添加到列表中,该列表位于哈希表中
- C++将项目添加到集合中
- C++:每当将元素添加到集合中时,如何调用函数
- 将向量的元素添加到无序集合中
- 无法将对象上的指针添加到集合
- 在运行时向对象添加函数集合
- 指针集合和添加对象
- 如何检索添加到由其超类对象组成的集合中的派生对象
- 将不可比较的对象添加到集合中
- 在集合之间交换(删除/添加)
- C++:为什么返回false的集合顺序的函子只允许向集合中添加一个元素
- 使用MSXML 6.0向SAXXMLReader60实例添加模式集合
- 添加c++对象到Objective C集合(NSSet)的麻烦
- 在C++中添加到集合之前或之后
- 如何在c++中为自己的集合类添加foreach迭代支持?
- 在c++中添加到集合中