从概念上了解容器上的位置访问操作

时间:2019-01-20 10:31:23

标签: c++ data-structures stl containers terminology

在容器上,位置访问操作 的定义看起来像什么,对我来说,std::vector似乎很简单, std::dequestd::liststd::forward_list。也就是说,访问集合中的第k th 个元素包括获取存储在第k th 个位置的元素。 在集合中 X

例如,表达式vec[k-1]访问k中的std::vector th ,而*std::next(lst.begin(), k-1)对应于其std::list

但是,当涉及到std::setstd::unordered_set之类的关联容器时,我不清楚是在谈论位置访问操作实际上是有道理的,因为我找不到在这种容器中确定任意位置k th 的简单方法。

但是,我们仍然可以按照上面显示的std::list示例进行操作,即,将迭代器带到关联容器的“第一个”元素(例如,成员函数{{1返回的迭代器) }}),然后将迭代器向前移动 k-1 次(例如,借助begin())。

我注意到容器std::next()std::vectorstd::dequestd::list都是使用 linear 数据结构实现的,而{通常不是实现为二叉树的{1}}不是。因此,也许这个问题与容器实现的基础数据结构的 linearity 有关。

是否有任何方法可以清楚地定义关联容器的位置访问操作的语义?还是这样的访问操作不适用


请勿混淆 search access 操作。在搜索操作中,您要在集合中寻找具有给定键的元素。


X 这与执行所需的运行时间无关(例如,std::forward_list是线性的,而不是std::set是恒定的时间)或是否存在没有专用的成员函数(例如,std::list中缺少下标运算符)即可实现。

2 个答案:

答案 0 :(得分:3)

您提到的容器类别之间的最大区别是,第一个是 sequence 容器,其中容器的用户明确确定放置元素的位置,而第二个容器是关联容器,其中根据元素的某些属性隐式确定结果顺序,从而可以通过键(std::map / std::unordered_map)/值(std::set来访问它们/ std::unordered_set)。

这并不意味着按这样的容器中的“位置”访问是没有用的-因为std::set保持其元素排序,第k个 项位于std::set中是集合中第k个 th 个最小元素(尽管实际上我无法想到按位置访问std::unordered_set的任何目的-哈希通常不会产生任何特别有用的ordering 1 )。

除了这种概念上的区别,在访问std::list的第k 个元素与在std::set上进行相同操作之间,在操作上没有太大的区别-在在这两种情况下,容器都不“本地”支持该操作(例如,容器不支持O(1)随机访问),并且您必须一次将其遍历一个元素。即使在幕后,走诸如std::setstd::map通常采用的二叉树与跟踪链接列表(例如std::list中的链接)也没有什么不同。 / p>


  1. 如果std::hash是一个加密哈希,将原始数据“白化”,则在“访问随机排列的某些元素”方面可能有些微不足道,但是std::hash仅需要在类型范围内分布良好,例如整数are often hashed as themselves-不是特别有趣的排列。

答案 1 :(得分:1)

正如您为列表所指出的那样,可以定义第k th 个元素,该元素由指针所指向,该指针位于指向k th-1的指针旁边元素。

您还会注意到,在数论中,数字也被定义为序列: 1是0旁边的数字,2是1旁边的数字,等等...

因此,人们可以通过指向容器元素及其下一个操作的指针以及通过+1操作指向自然数的结构,来形成结构的同构:

p0:=begin()                               O
  |next                                   |increment
p1:=next(begin())   --isomorphic to-->    1:=increment(0)
  |next                                   |increment
p2:=next(next(begin()))                   2:=increment(increment(0))
  .                                       .
  .                                       .

此同构可用于任何容器,只要它们提供开始指针即可。因此,出于位置概念的考虑,任何STL容器都是等效的。