It's getting complicated now. You are having to mix byte level and bit level granularities.
I was preparing this answer for your previous post #18 so I guess you have solved most of the problems. The last byte will be a special case because it may be only partially filled, so you have to somehow maintain an indication of how many bit in it are relevant.
Your queue ( or "circular buffer" or "fifo" ) is a byte queue. You are packing each byte with a full or (part ) 2 or 3 bit code which can flow over byte boundaries. However, once you have completely filled a byte in the queue and the bit pointer is pointing into the new byte, that old byte now is a candidate for being consumed from the queue and stored in EEPROM. You have to anyway maintain a pointer to the byte at the tail of the queue for the next data item to extract. You have to ensure that that pointer does not point to a byte which is in the process of being filled.
You don't have to worry about what the byte contains ( it could be a whole or parts of any 2 or 3 bit code ). That is only a problem when you start reading back from the EEPROM , which you do in units of one byte, and want to restore the original (decoded) data. But the idea of the Huffman coding scheme is that it is completely unambiguous. After reading (in this case) 2 bits from the data stream or array, you know if you then have to (or not) read a third bit to extract the original data item.
I once used a pre-existing software demodulator for one of my projects and I spend some time analysing the original code which contained a very simple, but clever implementation of a C/C++ queue. The original is here https://github.com/markqvist/LibAPRS/blob/master/src/FIFO.h and may help you. Because the queue was intended to be used by asynchronous processes, some protection is built in to prevent access conflicts which may not be relevant in your case. Or you may find a better one.