SGI STL容器概述

来源:互联网 发布:展柜制作成本核算软件 编辑:程序博客网 时间:2024/06/05 16:33

容器,顾名思义,置物之所也,这里的物指的是数据。根据“数据在容器中的排列”特性,容器可分为序列式容器和关联式容器两种,如下图所示:


所谓关联式容器,观念上类似关联式数据库:每个数据都有一个键值和实值。当数据插入到关联式容器中时,容器内部结构(可能是RB_Tree,也可能是hashtable)依照其键值大小,以某种特定规则将其放置于适当位置。标准的STL关联式容器分为set(集合)和map(映射表)两大类,以及这两大类的衍生体multiset(多键集合)、multimap(多键映射表)。这些容器的底层机制均以RB_Tree完成。RB_Tree也是一个单独的容器,单并不对外开放。

set的特性是所有的元素都会根据键值自动排序,因此不能直接改变元素的值,否则会打乱原本正确的位置,只能先删除该元素然后插入新元素;不存在直接存取元素的任何操作函数,元素的存取只能通过迭代器进行存取,而且对于迭代器而言元素的值是常数;元素的比较只能用于型别相同的容器(即元素和排序准则必须相同)。set的元素不像map那样可以同时拥有键值和实值,set元素的实值就是键值,键值就是实值,set不允许有相同键值的元素。

map的特性是,所有的元素都会按照键值自动排序,map的所有元素都是pair,同时拥有键值和实值。pair的第一个元素被视为键值,第二个元素被视为实值。map不允许具有相同键值的元素存在。multiset与multimap可以允许相同键值的元素存在。

hash_set (散列集合)、hash_map(散列表)、hash_multiset (散列多键集合)、hash_multimap(散列多键表)是SGI STL提供的非标准的关联式容器,它们的底层都是用hashtable来实现的,元素的存储不具有自动排序功能。元素的存储位置是根据散列函数计算出来的,这就难免会有多个元素散列到同一个槽中,为了解决这种“碰撞”问题,我们可以使用如下方法:线性探测、二次探测、开链法。线性探测的原理:通过散列函数计算出元素的位置,如果该位置已有元素,那么就从该位置依序往下寻找(如果找到尾端还没找到位置,就返回到散列表的头部继续寻找),直到找到闲置位置为止。使用线性探测的条件是散列表足够大,从而为每个要存储的元素都能找到合适的位置。二次探测的原理:二次探测和一次探测的原理相似,假设根据散列函数计算出的槽的位置为H,那么我们依序尝试H+1、H+2^2、H+3^2、H+4^2......H+i*i,而不是像线性探测那样依序尝试H+1、H+2、、、H+i。不管是线性探测还是二次探测,要求的散列表都必须足够大。开链法:这种做法是在每个表格中维护一个list,散列函数为我们分配一个list,然后我们在那个list上执行插入删除和查找操作。SGI STL的hashtable就是采用的这种开链法。

0 0
原创粉丝点击