est ici une file d'attente FIFO à base de tableau assez simple:
struct queue {
T *store; // where T is the data type you're working with
size_t size; // the physical array size
size_t count; // number of items in queue
size_t head; // location to pop from
size_t tail; // location to push to
};
struct queue q;
q.store = malloc(sizeof *q.store * SIZE);
if (q.store)
{
q.size = SIZE;
q.count = q.head = q.tail = 0;
}
Pour pousser un élément, faire quelque chose comme ce qui suit:
int push(struct queue q, T new_value)
{
if (q.count == q.size)
{
// queue full, handle as appropriate
return 0;
}
else
{
q.store[q.tail] = new_value;
q.count++;
q.tail = (q.tail + 1) % q.size;
}
return 1;
}
Pops sont similaires
int pop(struct queue q, T *value)
{
if (q.count == 0)
{
// queue is empty, handle as appropriate
return 0;
}
else
{
*value = q.store[q.head];
q.count--;
q.head = (queue.head + 1) % q.size;
}
return 1;
}
Comme écrit, ceci est une file "circulaire"; les pointeurs head
et tail
s'enrouleront alors que les éléments sont poussés et sortent de la file d'attente.
Comme pour toute approche, cela a des points forts et des points faibles. C'est simple, et cela évite une gestion excessive de la mémoire (juste l'allocation du backing store). Juste mettre à jour count
est plus simple que d'essayer de le calculer à partir de head
et tail
.
L'extension du magasin de stockage n'est pas si simple; si le pointeur de la queue est enroulée autour, vous devrez passer tout après head
:
Before:
+---+---+---+---+---+
| x | x | x | x | x |
+---+---+---+---+---+
^^
| |
| +--- head
+------- tail
After:
+---+---+---+---+---+---+---+---+---+---+
| x | x | x | | | | | | x | x |
+---+---+---+---+---+---+---+---+---+---+
^ ^
| |
| +--- head
+------- tail
Aussi, si vous voulez quelque chose de plus sophistiqué qu'un simple FIFO, vous voudrez probablement utiliser une structure de données différentes que votre magasin de soutien.
alors pourquoi un tableau plutôt qu'une liste? – user3528438