好吧,我认为它是完全有序的,因为元素的位置取决于它们的哈希函数,因此如果这些对象是不可变的,那么在你将它们放入集合之后,它们的位置将保持不变。比如说,每次你打印你的集合时,你都会有完全相同的元素顺序。当然,在计算出它们的哈希函数之前,您无法预测它们的位置,但无论如何。
4 回答
通用/抽象数据类型
来自Aho、Hopcroft、Ullmann的集合定义:“数据结构和算法”,Addison-Wesely,1987:
集合是成员(或元素)的集合;[...]。一个集合的所有成员都是不同的,[...]
抽象数据类型集不具有有序或无序的特点。定义了一些对集合进行操作的方法 - 但它们都与排序无关(例如,参见Martin Richards:“数据结构和算法”)。
如果一个集合中的每个元素也在另一个集合中,则两个集合被视为相等 - 并且没有其他元素。
当你写下一个集合(以及一个集合的所有元素)时,你需要以某种顺序写下来。请注意,这只是适当集合的表示。
示例:包含元素一、二和三的集合可以写成{1, 2, 3}, {1, 3, 2}, {3, 1, 2} 等等。这些只是同一集合的不同表示。
具体实现
在不同的编程语言中,集合以不同的方式实现,并考虑到不同的用例。
在某些语言(如 python、JAVA)中,标准集实现不会在其接口中公开排序。
在某些语言(如 C++)中,标准集实现在其接口中公开排序。
示例(C++):
在内部,集合中的元素总是按照容器构造中特定的严格弱排序标准从低到高排序。
模板<class Key,class Compare=less,class Allocator=allocator>class set;
(参见C++ 集)。
散列函数(通常)不是一组外部可见或可修改的参数;此外,即使您有一个散列函数已知且特征良好的实现,您也无法指定散列值冲突时的行为。
通常的总结是,集合的实现可能会施加顺序,但接口不会。
您指的是集合的哪个定义?在我的理解中,«set» 是一个数据结构的名称,它包含许多独特的元素,通常允许添加和删除。其他一切都不能保证,可能会受到实施。
它并没有说没有顺序,但是每个有效的实现都没有特定的顺序。哈希表的使用很常见,但也可以使用任何类型的列表或树。
所以顺序可能是通过一个散列函数(已经有很多可能的实现),或者与添加顺序或......
将新元素添加到 HashSet 后,它会被修改,并且新元素可能会根据哈希值计算定位在任何位置。因此不维持先前的顺序。