tags:

views:

146

answers:

5

Due to specific requirements [*], I need a singly-linked list implementation that uses integer indices instead of pointers to link nodes. The indices are always interpreted with respect to a vector containing the list nodes.

I thought I might achieve this by defining my own allocator, but looking into the gcc's implementation of , they explicitly use pointers for the link fields in the list nodes (i.e., they do not use the pointer type provided by the allocator):

  struct _List_node_base
  {
    _List_node_base* _M_next;   ///< Self-explanatory
    _List_node_base* _M_prev;   ///< Self-explanatory
    ...
  }

(For this purpose, the allocator interface is also deficient in that it does not define a dereference function; "dereferencing" an integer index always needs a pointer to the underlying storage.)

Do you know a library of STL-like data structures (i am mostly in need of singly- and doubly-linked list) that use indices (wrt. a base vector) instead of pointers to link nodes?

[*] Saving space: the lists will contain many 32-bit integers. With two pointers per node (STL list is doubly-linked), the overhead is 200%, or 400% on 64-bit platform, not counting the overhead of the default allocator.

EDIT: I'm looking for a SLL implementation that defines nodes in the following manner:

  struct list_node
  {
    int _value;  ///< The value in the list
    int _next;   ///< Next node in the list
    ...
  }

_next is interpreted wrt. an implicit array or vector (must be provided externally to each method operating on the list).

EDIT2: After a bit more searching, I've found that the standard actually requires that allocators intended to be used with standard collections must define the pointer type to be equivalent with T*.

+6  A: 

Why are you using the STL list? Unless you have very specific requirements, you should be using vector or deque instead. If your reason for using the list was to increase insertion efficiency, you should note that a deque offers most of the advantages of both list and vector because it is not required to maintain contiguous storage, but uses arrays as it's underlying storage media.

EDIT: And regarding your desire for a list that offers operator[], such a structure does not exist (at least, does not exist and still conform to the STL). One of the key design ideas of the STL is that algorithms and containers offer only what they can efficiently. Considering offering operator[] on a linked list requires linear time for each access, that's not efficient.

Billy ONeal
You have completely misunderstood what I'm after.
zvrba
He's asking for a linked list of nodes within an array underlaying a custom allocator. `operator[]` relates to the array, not the list.
Potatoswatter
@Photoswatter: Then yes, I misunderstand why you'd have two containers tracking the exact same data.
Billy ONeal
@zvrba: Given the amount of upvotes against a single downvote (yours, I guess), maybe you need to provide a better explanation of what you need.
Gorpik
@Gorpik: No, it was not my downvote.Better explanation: i want a SLL implementation that uses integers to link nodes instead of pointers. An integer can be thought of as a pointer with implicit base address.If it's still not clear, then you can't answer my question anyway.
zvrba
@zvrba: I think Billy's talking about the structure that the integers in the list are indexing into. *That* would best be implemented as a `vector` or `deque`; those containers keep the storage overhead to a minimum. As for an SLL or DLL using integers instead of pointers: you're just going to have to write that part out. There's no standard container for that, and nobody made a library out of it because it's the kind of thing you do in an introductory data structures course, except you do it with pointers.
Mike DeSimone
@Mike: That's not a foregone conclusion; using integers as pointers would seem to be the main use of the `pointer` member of allocators. Containers that hard-code `*` *anywhere* do not support allocators fully.
Potatoswatter
A: 

One option that is a bit out there is to use Judy Arrays. They provide highly efficient storage and are computationally efficient. They are good for storing sets of integers; I don't know if that suits your problem.

Marcelo Cantos
+2  A: 

We had to write our own list containers to get exactly this. It's about a half day's work.

Crashworks
Yeah, it's not a lot of work, but I was still hoping to find a debugged implementation. I guess I'll have to bite the bullet and do it my self nevertheless :-)
zvrba
Be aware that on some architectures, the cost of iterating or otherwise indexing with a non-word int type (eg, a 16 bit short on a 64 bit platform) can be significant.
Crashworks
Thanks for the tip!
zvrba
A: 

If you're concerned about the memory overhead of the linked list for storing a large number of int values, you should definitely consider a vector or deque as Billy ONeal suggested.

The drawback to either of these containers when compared to a linked list comes when inserting elements. Either of deque or vector will have to copy elements if you insert items into the middle of the container (deque has a big advantage over vector if you're going to insert at the beginning of the container, and even has an advantage when adding to the end of the container).

However, copying int elements after insertion is really not a whole lot more costly than scanning a linked list to find an element by index. Since deque and vector can locate an element by index in constant time and since data structures are generally read far more often than they're modified, you'll probably see a net gain using either of deque or vector over a linked list of int that you access by index (even a custom version).

Michael Burr
+1  A: 

Boost.Interprocess (containers) provides slist container that uses the pointer type of the allocator. Maybe this is what you are looking for :)

Even if these containers are included in Boost.Interprocess they work perfectly on intraprocess memory. In addition the author has already made the separation and proposed to bots as Boost.Containers (Documentation/Source)

Vicente Botet Escriba
Hah, good idea, but I can't use boost :/
zvrba