When preparing for interviews, I was inspired by this post and wrote my own version of circular buffer.
Here’s some essense of circular buffer this data structure.
How many elements are in the buffer is calculated based on the write and read position.
How the calculation looks depends on whether the write position has flipped (wrapped around) or not.
If the write position has not wrapped around you can simply subtract the read position from the write position to know how many elements are in the buffer. If the write position has wrapped around (flipped) then the available space is equal to the capacity minus the read position plus the write position.
To keep track of whether the write position has flipped or not a special “flip marker” is used. That is where the name of the implementation comes from. Actually, in most cases you could just check if the write position is larger or smaller than the read position to detect if the write position has wrapped around. But, that doesn’t work when write position and read position are equal (the ring buffer is either completely full or completely empty).
publicclass{ Integer[] elements; int capacity; int writePtr = 0; int readPtr = 0;
public(int capacity){ this.capacity = capacity; elements = new Integer[capacity]; }
publicsynchronizedvoidput(Integer num){ if (elements[writePtr] != null) { thrownew IllegalStateException(); } // Put the element at the pointed position elements[writePtr] = num;
publicsynchronized Integer take(){ // If readPtr is pointing at a null position, meaning no element is in this circular buffer if (elements[readPtr] == null) { returnnull; }
// Record the element, and remove it Integer result = elements[readPtr]; elements[readPtr] = null;
publicsynchronizedintoccupiedSize(){ // If writePtr is ahead of readPtr if(writePtr > readPtr) { return writePtr - readPtr; } elseif(writePtr < readPtr) { // If readPtr is ahead of writePtr, meaning the writePtr has turned over return capacity - readPtr + writePtr; } else { // If writePtr == readPtr // If readPtr is pointing at an element if(elements[readPtr] != null) { return capacity; } else { // If readPtr is pointing no element return0; } } }
publicsynchronizedintremainingCapacity(){ return capacity - occupiedSize(); } publicsynchronizedvoidreset(){ writePtr = 0; readPtr = 0; elements = new Integer[capacity]; }
publicstaticvoidmain(String[] args){ CircularBuffer cb = new CircularBuffer(3);
近期评论