Model
Bytes ------------------------------------------------------------------------------------------------------------------------
A queue is also a table that limits the insert and delete locations.
The main operations are enqueue and dequeue.
Enqueue: queue operation. insert an element at the end of the table (rear.
Dequeue: this operation deletes the front element of a table.
This article uses cyclic array to implement GenericQueue. You need to specify capacity. The disadvantage is that the capacity is exceeded and cannot be dynamically increased. Of course, you can follow the list method to overcome this problem.
For the complete code, see myGithub (https://github.com/gnudennis/ds_c) (genric-queue.h
Generic-queue.c generic-queue-test.c)
Core code
Bytes ------------------------------------------------------------------------------------------------------------------------
0. Generic Queue Definition
typedef void *ElementAddr;typedef void (*PfCbFree)(ElementAddr);typedef struct QueueRecord{ ElementAddr*array; intcapacity; intelemsize; intfront; intrear; intsize; PfCbFreefreefn;} *Queue;
1. API
/* Create a new queue */Queue queue_create(int elemsize, int capacity, PfCbFree freefn);/* Dispose the queue */void queue_dispose(Queue que);/* Make the give queue empty */void queue_make_empty(Queue que);/* Return true if the queue is empty */int queue_is_empty(Queue que);/* Return true if the queue is full */int queue_is_full(Queue que);/* Insert a new element onto queue */void queue_enqueue(Queue que, ElementAddr elemaddr);/* Delete the front element off the queue */void queue_dequeue(Queue que);/* Fetch the front element from the queue */void queue_front(Queue que, ElementAddr elemaddr);/* Fetch and Delete the front element from the queue */void queue_front_and_dequeue(Queue que, ElementAddr elemaddr);
2. Implementation
/* Create a new queue with capacity */Queue queue_create(int elemsize, int capacity, PfCbFree freefn){ Queue que; que = malloc(sizeof(struct QueueRecord)); if ( que == NULL ) { fprintf(stderr, "Out of memory\n"); exit(1); } que->elemsize = elemsize; que->capacity = capacity > MIN_QUEUE_SIZE ? capacity : MIN_QUEUE_SIZE; que->array = malloc(elemsize * que->capacity); if ( que->array == NULL ) { fprintf(stderr, "Out of memory\n"); exit(1); } que->front = 1; que->rear = 0; que->size = 0; que->freefn = freefn; return que;}/* Dispose the queue */void queue_dispose(Queue que){ if (que != NULL) { queue_make_empty(que); free(que->array); free(que); }}/* Make the give queue empty */void queue_make_empty(Queue que){ if ( que->freefn ) { int i; for ( i = 0; i < que->size; ++i) { free((char *)que->array + que->elemsize * i); } } que->size = 0; que->front = 1; que->rear = 0;}/* Return true if the queue is empty */int queue_is_empty(Queue que){ return que->size == 0;}/* Return true if the queue is full */int queue_is_full(Queue que){ return que->size == que->capacity;}static int successor(Queue que, int index){ if ( ++index == que->capacity) index = 0; return index;}/* Insert a new element onto queue(rear) */void queue_enqueue(Queue que, ElementAddr elemaddr){ void *target; if ( queue_is_full(que) ) { fprintf(stderr, "Full queue\n"); exit(1); } que->rear = successor(que, que->rear); target = (char *)que->array + que->elemsize * que->rear; memcpy(target, elemaddr, que->elemsize); que->size++;}/* Delete the front element off the queue */void queue_dequeue(Queue que){ if ( queue_is_empty(que) ) { fprintf(stderr, "Empty queue\n"); exit(1); } if ( que->freefn ) { void *target = (char *)que->array + que->front * que->elemsize; que->freefn(target); } que->size--; que->front = successor(que, que->front);}/* Fetch the front element from the queue */void queue_front(Queue que, ElementAddr elemaddr){ void *target = (char *)que->array + que->front * que->elemsize; memcpy(elemaddr, target, que->elemsize);}/* Fetch and Delete the front element from the queue */void queue_front_and_dequeue(Queue que, ElementAddr elemaddr){ void *target; if ( queue_is_empty(que) ) { fprintf(stderr, "Empty queue\n"); exit(1); } target = (char *)que->array + que->front * que->elemsize; memcpy(elemaddr, target, que->elemsize); que->size--; que->front = successor(que, que->front);}
Analysis
----------------
This article uses a circular array to implement GenericQueue. You need to specify capacity. Since it is a circular array, It is a circle. Therefore, inserting the first element does not have to be placed at 0.
Initial status:
{
Que-> size = 0;
Que-> front = 1;
Que-> rear = 0;
}
This indicates that the first enqueue operation is placed in array [1]. Of course, this is not necessary, but it depends on where you want to put it.
# Define mxx
{
Que-> size = 0;
Que-> front = m + 1;
Que-> rear = m;
}
Put it in array [m + 1.