STL中的Set和Map

先来看一段网络上的文字描述:

STL中的Set和Map

上图是一段关于 STL 中 Set 集合的描述,同样的,也近似适合 Map 的描述。上述文字中,描述了最为重要的特征:

Set 和 Map ,底层调用了红黑树的结构,并且实现的是一种自动平衡二叉搜索树。

  • Set
STL中的Set和Map

平衡二叉搜索树(Set)

如上图, STL 中 Set 实现的本质是 平衡二叉搜索树,且树中没有相同的元素 ,每一个节点表示 Set 中的一个元素, Set 中只有键,也就是上述图中每个节点的值,就是 Set 的每个元素,因此 Set 中没有重复元素, 当向 Set 中执行 insert (插入)时,树会自动调整结构(对于红黑树而言,会实现节点的旋转),以保证树结构的平衡性 。当执行多次向节点中插入同一个键值时,比如 insert ( 5 ), insert ( 5 ),则只会执行第一次的 insert 操作。后续的插入,并不会执行,因为 Set 结构的树中无重复元素。

另一个点在于, Set 中被插入的键不能被修改,也就是通过迭代器修改键值是不被允许的 。因为键值一旦被修改,就意味着树的结构遭到了破坏,而这在最坏的情况意味着:整棵二叉树遭到了破坏,甚至需要重构整棵二叉树。即使在红黑树中,并没有这样的操作。因为红黑树的最为显著的特征为:局部调整。即对于 Set 而言,其 iterator 属于 const-iterator 。

另外一个需要被注意的点在于:

STL中的Set和Map

我们使用迭代器来访问容器是一件很平常的事情,上述代码是一段使用极其平常的代码,其作用是遍历 Set 中所有的元素。 注意循环的终止条件是: ! = , 而不是: < 。 我们通常习惯了小于的小法:

即:

STL中的Set和Map

但这样的写法是错误的。

  • Map

下面来看 Map , Map 的结构形成机理和 Set 几乎是一模一样的,而 Map 的结构如下:

STL中的Set和Map

"挂件"平衡二叉搜索树( Map )

Map 的结构如上图:可见,

Set 相比, Map 只是多了一个"挂件" , 也就是常说的 Map 是由:键—值对构成的。 键充当了索引,值则记录了一些其他内容 。而对于 Set 而言,只有键。或许我们用下面这个表来描述更为合适:

键—值对

索引序号 名字

1 张三

2 李四

3 王五

左边的索引号就是键,右边的名字就是值,所以说 Map 实际上是一种极为普遍简单的概念。这种关系就像字典一样。

而关于 Map 的其他性质,和 Set 是极其类似的。比如: 没有相同的元素 ,当然对于 Map 而言,没有相同的元素是只没有两个元素键相同。执行两个 insert ,仍然会只有键值对存在树中,只是第二次执行的 insert 会修改第一次的 键 - 值对中的值。

同样的, Map 中的键是不能被修改的 ,因为同样会导致"重建树"这个问题,但是很明显的是,

值明显是可以修改的 ,就像我们可以把上述索引序号为" 3 "的"王五"修改为"赵六";但我们不能将索引号 3 修改为 4, (我们只能将 3 删除,再添加 4 ,这是可以的)。当然是用迭代器访问时, 其也只能用 != ,而不是 <


分享到:


相關文章: