Reputation: 8869
I was wondering if there was a simple data structure that supports amortized log(n) lookup and insertion like a self balancing binary search tree but with constant memory overhead. (I don't really care about deleting elements).
One idea I had was to store everything in one contiguous block of memory divided into two contiguous blocks: an S part where all elements are sorted, and a U that isn't sorted.
To perform an insertion, we could add an element to U, and if the size of U exceeds log(size of S), then you sort the entire contiguous array (treat both S and U as one contiguous array), so that after the sort everything is in S and U is empty.
To perform lookup run binary search on S and just look through all of U.
However, I am having trouble calculating the amortized insertion time of my algorithm.
Ultimately I would just appreciate some reasonably simple algorithm/datastructure with desired properties, and some guarantee that it runs reasonably fast in amortized time.
Thank you!
Upvotes: 4
Views: 548
Reputation: 32335
If by constant amount of memory overhead you mean that for N
elements stored in the data-structure the space consumption should be O(N)
, then any balanced tree will do -- in fact, any n
-ary tree storing the elements in external leaves, where n > 1
and every external tree contains an element, has this property.
This follows from the fact that any tree graph with N
nodes has N - 1
edges.
If by constant amount of memory overhead you mean that for N
elements the space consumption should be N + O(1)
, then neither the balanced trees nor the hash tables have this property -- both will use k * N
memory, where k > 1
due to extra node pointers in the case of trees and the load factor in the case of hash tables.
I find your approach interesting, but I do not think it will work even if you only sort U, and then merge the two sets in linear time. You would need to do a sort (O(logN * log(logN))
operations) after every logN
updates, followed by an O(n)
merging of S and U (note that so far nobody actually knows how to do this in linear time in place, that is, without an extra array).
The amortized insertion time would be O(n / logN)
. But you could maybe use your approach to achieve something close to O(√n)
if you allow the size of U to grow to the square root of S.
Upvotes: 1
Reputation: 1176
Any hashtable will do that. The only tricky part about it is how you resolve conflicts - there are few ways of doing it, the other tricky part is correct hash computing.
See: http://en.wikipedia.org/wiki/Hash_table
Upvotes: 0