In terms of big-O runtime, it seems that both data structures have in the "average" case:
O(1)
insertion/removal into the start and endO(n)
insertion/removal into some arbitrary indexO(1)
lookup of the start and end
Advantages of circular buffer:
O(1)
lookup instead ofO(n)
of some arbitrary index- Doesn't need to create nodes, thus doesn't need a dynamic allocation on each insertion
- Faster traversal due to better cache prediction
- Faster removal due to vectorization (e.g. using
memmove
) to fill the gap - Typically needs less space (because in a linked list, for each node, you have to sort pointers to the next and/or previous node)
Advantages of linked list:
- Easier to get
O(1)
insertion/removal to some specific place (e.g., could get it for midway through the linked list). Circular buffers can do it, but it's more complicated O(1)
insertion in the worst case, unlike circular buffers that areO(n)
(when it needs to grow the buffer)
Based on this list, it seems to me that circular buffers are a far better choice in almost every case. Am I missing something?