// Implementação do TAD fila genérica
-/* PEDRO HENRIQUE FRIEDRICH RAMOS : GRR20243133 */
+/* PEDRO HENRIQUE FRIEDRICH RAMOS : GRR20243133 */
#include "queue.h"
#include <stdio.h>
#include <stdlib.h>
+/* ------------------------------------------------------------------------- */
+/* Data types ------------------------------------------------------------- */
+
+/* Queue element. */
struct node_t
{
- void *item;
- struct node_t *next;
+ void *item; /* User provided opaque pointer. */
+ struct node_t *next; /* Pointer to the next node in the queue. */
};
+/* ------------------------------------------------------------------------- */
+
+/* Queue. */
struct queue_t
{
- struct node_t *head;
- struct node_t *tail;
- struct node_t *iterator;
- int size;
+ struct node_t *head; /* Pointer to the first node in the queue. */
+ struct node_t *tail; /* Pointer to the last node in the queue. */
+ struct node_t *iterator; /* Pointer to the current node. */
+ int size; /* Number of nodes in the queue. */
};
+/* ------------------------------------------------------------------------- */
+/* Internal functions ----------------------------------------------------- */
+
static inline struct node_t *
node_create (void)
{
return calloc (1, sizeof (struct node_t));
}
+/* ------------------------------------------------------------------------- */
+
static inline void
node_destroy (struct node_t *node)
{
free (node);
}
+/* ------------------------------------------------------------------------- */
+/* Exported functions ----------------------------------------------------- */
+
struct queue_t *
queue_create (void)
{
return calloc (1, sizeof (struct queue_t));
}
+/* ------------------------------------------------------------------------- */
+
int
queue_destroy (struct queue_t *queue)
{
while (n)
{
+ /* Save the next node pointer before destroying the current node. */
next = n->next;
node_destroy (n);
n = next;
return NOERROR;
}
+/* ------------------------------------------------------------------------- */
+
int
queue_add (struct queue_t *queue, void *item)
{
n->item = item;
++queue->size;
+ /* Empty queue, this is the first element. */
if (!queue->head)
{
queue->head = queue->tail = queue->iterator = n;
return NOERROR;
}
+ /* Append to queue. */
queue->tail = queue->tail->next = n;
return NOERROR;
}
+/* ------------------------------------------------------------------------- */
+
int
queue_del (struct queue_t *queue, void *item)
{
if (!queue || !item)
return ERROR;
- if (!(n = queue->head))
+ if (!(n = queue->head)) /* Queue is empty. */
return ERROR;
prev = NULL;
n = n->next;
}
- if (!n) /* not found */
+ if (!n) /* Not found. */
return ERROR;
if (prev)
prev->next = n->next;
+ /* Update boundaries accordingly. */
if (queue->head == n)
queue->head = n->next;
if (queue->tail == n)
queue->tail = prev;
+ /* Advance the iterator if it points to the removed node. */
if (queue->iterator == n)
queue->iterator = n->next;
return NOERROR;
}
+/* ------------------------------------------------------------------------- */
+
bool
queue_has (struct queue_t *queue, void *item)
{
if (!(n = queue->head))
return false;
+ /* Traverse until the item is found or the end is reached. */
while (n->item != item && (n = n->next))
;
return n != NULL;
}
+/* ------------------------------------------------------------------------- */
+
int
queue_size (struct queue_t *queue)
{
return queue->size;
}
+/* ------------------------------------------------------------------------- */
+
void *
queue_head (struct queue_t *queue)
{
return queue->head->item;
}
+/* ------------------------------------------------------------------------- */
+
void *
queue_next (struct queue_t *queue)
{
return queue->iterator->item;
}
+/* ------------------------------------------------------------------------- */
+
void *
queue_item (struct queue_t *queue)
{
return queue->iterator->item;
}
+/* ------------------------------------------------------------------------- */
+
void
queue_print (char *name, struct queue_t *queue, void (func) (void *))
{
printf ("] (%d items)\n", queue->size);
}
+
+/* ------------------------------------------------------------------------- */