I wrote GrabBag as a datastructure to hold genetically evolving programs (see OGPF). Unlike most collections, this one assumes that when you add an element you don't care where it goes (unordered insertion) and that when you pull out an element you specifically want a uniformly random element.
See the grabbag directory for the source code (GPLed unless you talk to me).
This particular implementation is based on a binary tree which keeps track of how many leaves it has on both its left and right side (the actual data is stored in the leaves). This makes it easy to find the size -- you just add those two numbers from the root of the tree. To grab something at random we take the size (total number of things we have), pick a random number up to that. Then we start at the root... if the number is bigger than the left, we go right and so on until we find the node and pull it out. We make a note of the removal by subtraction on the way back out. 2^n
nodes can thus be accessed in 2*n
operations (which is equivalent to O(ln n)
I believe). Adding works similarly -- we move down the tree finding out where it is lopsided and add the new thingie there, thereby keeping things pretty even.