views:

344

answers:

7

I have come up with a data structure that combines some of the advantages of linked lists with some of the advantages of fixed-size arrays. It seems very obvious to me, and so I'd expect someone to have thought of it and named it already. Does anyone know what this is called:

Take a small fixed-size array. If the number of elements you want to put in your array is greater than the size of the array, add a new array and whatever pointers you like between the old and the new.

Thus you have:

Static array
—————————————————————————
|1|2|3|4|5|6|7|8|9|a|b|c|
—————————————————————————

Linked list
————  ————  ————  ————  ————
|1|*->|2|*->|3|*->|4|*->|5|*->NULL
————  ————  ————  ————  ————

My thing:
————————————  ————————————
|1|2|3|4|5|*->|6|7|8|9|a|*->NULL
————————————  ————————————

Edit: For reference, this algorithm provides pretty poor worst-case addition/deletion performance, and not much better average-case. The big advantage for my scenario is the improved cache performance for read operations.

Edit re bounty: Antal S-Z's answer was so complete and well-researched that I wanted to provide em with a bounty for it. Apparently Stack Overflow doesn't let me accept an answer as soon as I've offered a bounty, so I'll have to wait (admittedly I am abusing the intention bounty system somewhat, although it's in the name of rewarding someone for an excellent answer). Of course, if someone does manage to provide a better answer, more power to them, and they can most certainly have the bounty instead!

Edit re names: I'm not interested in what you'd call it, unless you'd call it that because that's what authorities on the subject would call it. If it's a name you just came up with, I'm not interested. What I want is a name that I can look up in text books and with Google. (Also, here's a tip: Antal's answer is what I was looking for. If your answer isn't "unrolled linked list" without a very good reason, it's just plain wrong.)

A: 

I would call this a bucket list.

fubra
A: 

You can call it LinkedArrays.

Also, I would like to see the pseudo-code for the removeIndex operation.

eljenso
Please read the question (particularly now I've added an addendum). I'm not interested in what you'd call it. I'm interested in what it's called. You might call a cat a waffleopalus, but if you want to talk about your pet, it's only going to be useful to other people if you talk about it using the word "cat".
me_and
A: 

While I don't know your task, I would strongly suggest you have a look at skip lists.

As for name, I'm thinking a bucket list would probably be most apropos

jer
+1 for skip lists.
Xavier Ho
Please read the question (particularly now I've added an addendum). I'm not interested in what you'd call it. I'm interested in what it's called. You might call a cat a waffleopalus, but if you want to talk about your pet, it's only going to be useful to other people if you talk about it using the word "cat".
me_and
+1  A: 

CDR coding (if you're old enough to remember Lisp Machines).

Also see ropes which is a generalization of this list/array idea for strings.

Doug Currie
CDR coding appears to do something different that what I'm after. As Antal points out (and Wikipedia links to at the end of that article), unrolled linked lists are what I'm after.
me_and
A: 

What are the advantages of this data structure in terms of insertion and deletion? Ex: What if you want to add an element between 3 and 4? still have to do a shift, it takes O(N) How do you find out the correct bucket for elementAt?

I agree with jer, you must take a look on skip list. It brings the advantages of Linked List and Arrays. The most of operations are done in O(log N)

rkitauchi
+9  A: 

It's called an unrolled linked list. There appear to be a couple of advantages, one in speed and one in space. First, if the number of elements in each node is appropriately sized (e.g., at most the size of one cache line), you get noticeably better cache performance from the improved memory locality. Second, since you have O(n/m) links, where n is the number of elements in the unrolled linked list and m is the number of elements you can store in any node, you can also save an appreciable amount of space, which is particularly noticeable if each element is small. When constructing unrolled linked lists, apparently implementations will try to generally leave space in the nodes; when you try to insert in a full node, you move half the elements out. Thus, at most one node will be less than half full. And according to what I can find (I haven't done any analysis myself), if you insert things randomly, nodes tend to actually be about three-quarters full, or even fuller if operations tend to be at the end of the list.

And as everyone else (including Wikipedia) is saying, you might want to check out skip lists. Skip lists are a nifty probabilistic data structure used to store ordered data with O(log n) expected running time for insert, delete, and find. It's implemented by a "tower" of linked lists, each layer having fewer elements the higher up it is. On the bottom, there's an ordinary linked list, having all the elements. At each successive layer, there are fewer elements, by a factor of p (usually 1/2 or 1/4). The way it's built is as follows. Each time an element is added to the list, it's inserted into the appropriate place in the bottom row (this uses the "find" operation, which can also be made fast). Then, with probability p, it's inserted into the appropriate place in the linked list "above" it, creating that list if it needs to; if it was placed in a higher list, then it will again appear above with probability p. To query something in this data structure, you always check the top lane, and see if you can find it. If the element you see is too large, you drop to the next lowest lane and start looking again. It's sort of like a binary search. Wikipedia explains it very well, and with nice diagrams. The memory usage is going to be worse, of course, and you're not going to have the improved cache performance, but it is generally going to be faster.

References

Antal S-Z
Exactly what I was looking for, thank you!
me_and
I don't think skip lists are going to do the job given your description; the primary reason for me wanting to use unrolled linked lists is for the cache performance.
me_and
You only lose the cache performance if you implement it in a node centric way. Look at thinking about it from a cache friendly manner, and you can implement skip lists that are cache friendly.
jer
jer: Interesting. Do you have any tips on how to do that, or any links/papers? I'm not really well acquainted with this sort of design, and so I don't see how immediately.
Antal S-Z
The idea is to store the nodes really in a contiguous space on a single threaded platform. It's not that you access it like an array or anything, but you can typically (and this is seen really well on modern platforms with multiple cores and whatnot) store read-only copies of the lists in the caches of each core if they're concurrently working on a list, they're quite happy to do that, and we only have to hand off the data that changed if it affects other data, which it typically won't (i.e., worst case, we have to invalidate the data in one cache line of another core in doubly list update)
jer
A: 

Basically, i would call this an ArrayLinkedList since it's linked list of array.

hoang
Please read the question (particularly now I've added an addendum). I'm not interested in what _you'd_ call it. I'm interested in what it's called. You might call a cat a waffleopalus, but if you want to talk about your pet, it's only going to be useful to other people if you talk about it using the word "cat".
me_and
So you might be deaf, since an "unrolled linked list" is "exactly what you were looking for" you should mark it as answered. Though, all developpers next to me don't know what an unrolled linked list is but when I show them the structure we all agree to say it's just a linked list of array... Here we now call you a "boulet" and it is useful to describe you in a blink of an eye.
hoang
As noted in the question, I couldn't mark it as answered at the time as I'd just offered a bounty.As you say, it's just a linked list of arrays, but such structures often get an accepted name that rolls off the tongue a little better, and rolls into textbooks and Google a little easier. "String" for "array of characters", for example; Googling for "linked list of arrays" provides nothing useful, while "unrolled linked list" does.My French isn't very good, I'm afraid. The best I can get for "boulet" is cannonball. Any translation?
me_and