由于特定的要求[*],我需要一个单链表实现,它使用整数索引而不是链接节点的指针。索引总是根据包含列表节点的向量进行解释。
我想我可以通过定义自己的分配器来实现这一点,但是在查看gcc的实现时,它们明确地使用指针列表节点中的链接字段(即,它们不使用分配器提供的指针类型) :
struct _List_node_base
{
_List_node_base* _M_next; ///< Self-explanatory
_List_node_base* _M_prev; ///< Self-explanatory
...
}
(为此,分配器接口也缺点在于它没有定义解引用函数;“解除引用”整数索引总是需要指向底层存储的指针。)
你知道一个类似STL的数据库(我主要需要单链和双链表)使用索引(wrt。基矢量)而不是指向链接节点的指针吗?
[*]节省空间:列表将包含许多 32位整数。每个节点有两个指针(STL列表是双向链接的),64位平台上的开销是200%或400%,不计算默认分配器的开销。
编辑:我正在寻找以下列方式定义节点的SLL实现:
struct list_node
{
int _value; ///< The value in the list
int _next; ///< Next node in the list
...
}
_next被解释为wrt。隐式数组或向量(必须在列表上运行的每个方法外部提供)。
EDIT2:经过一番搜索后,我发现标准实际上要求与标准集合一起使用的分配器必须将指针类型定义为与T *等效。
答案 0 :(得分:5)
为什么使用STL列表?除非您具有 非常 特定要求,否则您应该使用vector
或deque
。如果您使用该列表的原因是为了提高插入效率,您应该注意deque
提供了list
和vector
的大多数优势,因为它不需要维护连续存储,但使用数组作为它的底层存储介质。
编辑:关于您对提供operator[]
的列表的期望,这样的结构不存在(至少,不存在并且仍然符合STL)。 STL的一个关键设计思想是算法和容器只提供他们可以高效的东西。考虑在链表上提供operator[]
需要每次访问的线性时间,这是无效的。
答案 1 :(得分:3)
我们必须编写自己的列表容器才能得到这个。这是大约半天的工作。
答案 2 :(得分:1)
Boost.Interprocess(容器)提供使用分配器的指针类型的slist容器。也许这就是你要找的东西:)
即使这些容器包含在Boost.Interprocess中,它们也能完美地处理进程内存。此外,作者已经进行了分离,并建议机器人为Boost.Containers(Documentation / Source)
答案 3 :(得分:0)
有一个选项是使用Judy Arrays。它们提供高效的存储并且计算效率高。它们适用于存储整数集;我不知道这是否适合你的问题。
答案 4 :(得分:0)
如果您担心链接列表的内存开销会存储大量int
值,那么您一定要考虑vector
或deque
as Billy ONeal suggested
与插入链接列表相比,这些容器中的任何一个都存在缺陷。如果您将项目插入容器的中间,则deque
或vector
中的任何一个都必须复制元素(如果您要在开头插入,deque
比向量具有更大的优势容器的容器,甚至在添加到容器的末端时具有优势。
但是,在插入后复制int
元素实际上并不比扫描链表以按索引查找元素要昂贵得多。由于deque
和vector
可以在常量时间内按索引定位元素,并且由于数据结构通常比修改它们更频繁地读取,因此您可能会看到使用{{{ 1}}或deque
覆盖您通过索引访问的vector
链接列表(甚至是自定义版本)。