Yet another approach (as additional to linked-list) is to use map of stacks. In that case you'll have to use additional log(3^n)/log(2) bits for building map of data distribution in your n-length array. Each of 3-value part of map says which stack is owns next element.
Ex. a.push(1); b.push(2); c.push(3); a.push(4); a.push(5);
will give you image
aacba
54321
appropriate value of map is calculated while elements is pushed onto stack (with shifting contents of array)
map0 = any
map1 = map0*3 + 0
map2 = map1*3 + 1
map3 = map2*3 + 2
map4 = map3*3 + 0
map5 = map4*3 + 0 = any*3^5 + 45
and length of stacks 3,1,1
Once you'll want to do c.pop()
you'll have to reorganize your elements by finding actual position of c.top()
in original array through walking in cell-map (i.e. divide by 3 while mod by 3 isn't 2) and then shift all contents in array back to cover that hole. While walking through cell-map you'll have to store all position you have passed (mapX
) and after passing that one which points to stack "c" you'll have to divide by 3 yet another time and multiply it by 3^(amount positions passed-1) and add mapX
to get new value of cells-map.
Overhead for that fixed and depends on size of stack element (bits_per_value
):
(log(3**n)/log(2)) / (n*log(bits_per_value)/log(2)) = log(3**n) / (n*log(bits_per_value)) = log(3) / log(bits_per_value)
So for bits_per_value = 32
it will be 31.7% space overhead and with growing bits_per_value
it will decay (i.e. for 64 bits it will be 26.4%).