unordered_set

template < class Key,                        // unordered_set::key_type/value_type
           class Hash = hash,           // unordered_set::hasher
           class Pred = equal_to,       // unordered_set::key_equal
           class Alloc = allocator      // unordered_set::allocator_type
           > class unordered_set;

 

无序集是不按特定顺序存储唯一元素的容器,它允许根据单个元素的值快速检索单个元素。在unordered_set中,元素的值同时是其键,它唯一地标识它。键是不可变的,因此,unordered_set中的元素不能在容器中修改一次 - 但是可以插入和删除它们。

在内部,unordered_set中的元素没有按任何特定顺序排序,但是根据它们的哈希值组织成桶,以允许通过它们的值直接快速访问各个元素(平均时间复杂度恒定)。

unordered_set容器比通过其键访问单个元素的set容器更快,尽管它们通过其元素子集的范围迭代通常效率较低。

unordered_set特性:

       联想:关联容器中的元素由其引用,而不是由它们在容器中的绝对位置引用。

       无序:无序容器使用哈希表来组织其元素,这些哈希表允许通过快速访问元素。

       组:元素的值也是用于标识它的

       独特的钥匙:容器中没有两个元素可以具有等效

       分配器感知:容器使用allocator对象来动态处理其存储需求。

注意:unordered_set中的所有迭代器都指向const元素。

参数说明:

 n -- 初始桶的最小数量。 这不是容器中元素的数量,而是构造时内部哈希表所需的最小插槽数。如果未指定此参数,则构造函数会自动确定(以某种方式取决于特定的库实现)

hf -- Hasher功能对象。 hasher是一个函数,它根据作为参数传递给它的容器对象键返回一个整数值.成员类型hasher在unordered_set中定义为其第二个模板参数(Hash)的别名。

eql -- 比较函数对象,如果作为参数传递的两个容器对象键被认为是相等的,则返回true。成员类型key_equal在unordered_set中定义为其第三个模板参数(Pred)的别名。

alloc -- 要使用的分配器对象而不是构造新的对象。

first last -- 将迭代器输入到范围中的初始位置和最终位置。使用的范围是[first,last),其中包括first和last之间的所有元素,包括first指向的元素,但不包括last指向的元素。

il -- initializer_list对象。 这些对象是从初始化列表声明符自动构造的。

构造函数例子:

// constructing unordered_sets
#include 
#include 
#include 

template
T cmerge (T a, T b) { T t(a); t.insert(b.begin(),b.end()); return t; }

int main ()
{
  std::unordered_set first;                                // empty
  std::unordered_set second ( {"red","green","blue"} );    // init list
  std::unordered_set third ( {"orange","pink","yellow"} ); // init list
  std::unordered_set fourth ( second );                    // copy
  std::unordered_set fifth ( cmerge(third,fourth) );       // move
  std::unordered_set sixth ( fifth.begin(), fifth.end() ); // range

  std::cout << "sixth contains:";
  for (const std::string& x: sixth) std::cout << " " << x;
  std::cout << std::endl;

  return 0;
}

输出:

sixth contains: pink yellow red green orange blue

 

因为元素在unordered_set中根据key值,通过相应的hash()函数得到关键码值,关键码值对应着一个相应的位置,用该位置存储相应的信息。容器中的元素无特别的秩序关系,该容器允许基于值的快速元素检索,同时也支持正向迭代。在一个unordered_set内部,元素不会按任何顺序存储,而是通过元素值的哈希值,存放在各个槽中,(Bucker,也可以译为“桶”),这样就可以通过元素值快速找到各个值。

nordered_set::begin()

container iterator (1)
      iterator begin() noexcept;
const_iterator begin() const noexcept;
bucket iterator (2)
      local_iterator begin ( size_type n );
const_local_iterator begin ( size_type n ) const;

 

返回指向unordered_set容器(1)或其中一个存储桶(2)中的第一个元素的迭代器。请注意,unordered_set对象不保证哪个特定元素被视为其第一个元素。但是,在任何情况下,从开始到结束的范围都涵盖容器(或存储桶)中的所有元素,直到无效。

返回值:容器(1)或存储桶(2)中第一个元素的迭代器。

例子:

#include
#include
#include
int main()
{
    std::unordered_set myset=     
          {"Mercury","Venus","Earth","Mars","Jupiter","Saturn","Uranus","Neptune"};
    std::cout << "myset contains:";
  
    for ( auto it = myset.begin(); it != myset.end(); ++it )
        std::cout << " " << *it;
          std::cout << std::endl;

    std::cout<<"myset's bukets contain:\n";
    for(unsigned int i=0;i

输出:

myset contains: Venus Jupiter Neptune Mercury Earth Uranus Saturn Mars
myset's buckets contain:
bucket #0 contains:
bucket #1 contains: Venus
bucket #2 contains: Jupiter
bucket #3 contains: 
bucket #4 contains: Neptune Mercury
bucket #5 contains: 
bucket #6 contains: Earth
bucket #7 contains: Uranus Saturn
bucket #8 contains: Mars
bucket #9 contains: 
bucket #10 contains: 

为啥同一个bucket存在多个值,因为它们的哈希值得到的关键码相同,冲突是不可避免的,而解决冲突的方法常见的有:开发地址法、再散列法、链地址法(也称拉链法)。而unordered_set内部解决冲突采用的是----链地址法,当用冲突发生时把具有同一关键码的数据组成一个链表。下图展示了链地址法的使用:

unordered_set :: bucket()

size_type bucket(const key_type&k)const;

找到元素的存储桶,返回值为K的元素所在的桶编号。

存储桶是容器内部哈希表中的一个插槽,根据其哈希值为其分配元素。存储桶的编号从0到(bucket_count -1)。

可以通过unordered_set :: begin和unordered_set :: end返回的范围迭代器访问存储桶中的各个元素。

// unordered_set::bucket
#include 
#include 
#include 

int main ()
{
  std::unordered_set myset = {"water","sand","ice","foam"};

  for (const std::string& x: myset) {
    std::cout << x << " is in bucket #" << myset.bucket(x) << std::endl;
  }

  return 0;
}

你可能感兴趣的:(C++)