In liberal C:
/* i'm using this */
struct QueueItem
{
QueueItem* next;
void* data;
}
struct Queue
{
QueueItem* head;
QueueItem* tail;
}
/*
+---+ +---+
|0 0| |* *| len 1
+---+ +|-|+
v v
len +---+
0 |d 0|
+---+
+---+
|* *---------...---+
+|--+ | len n
v v
+---+ +---+ +---+
|a *-->|b *--...->|z 0|
+---+ +---+ +---+
*/
This gives O(1) for all push/pop/peek and O(n) traversal, but uses 2+2n memory. A naive array version give a minimum of 2+n (about optimal), but is usually worse, and sometimes causes modifications to take longer (for reallocation).
struct Queue
{
size_t len;
size_t head;
void (*data)[];
}
/*
+-----+
|* * *-----~~~-+
+|-|--+ |
v +-+ |
+----v-----~~~-v+
|0 0 a b c . . z|
+----------~~~--+
*/
It looks like there is no way to improve memory usage with sacrificing preformance, but i wanted to at least put this out there in case anyone knows a way around this.
Edit (because i cant have code in comments):
struct QueueItem
{
QueueItem* next;
size_t len;
void (*data)[];
}
struct Queue
{
QueueItem* head;
QueueItem* tail;
size_t start;
size_t end; //edit: need to know where to push data. edit: not per-item
}
/*
+-----+
|* * *------------------------------+
+|-|--+ |
v +---+ (2x longer) v (much longer)
+------v----+ +-----------+ +---------------+
|@ 0 0 a b *-->|@ c . . h *-->...->|@ . . . x y z 0|
+-----------+ +-----------+ +---------------+
*/