Algorithms/source/handyqueue.h

129 lines
2.9 KiB
C
Raw Normal View History

2017-05-23 19:35:24 +00:00
/*
handyqueue.h
Created By:
Andrew Lalis (andrewlalisofficial@gmail.com)
23 May 2017
This file is free to use, as long as the above comment remains in the file.
Please contact the author regarding bugs and/or feature requests.
*/
#ifdef QUEUE_TYPE
#include "templates.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
2017-10-02 10:40:39 +00:00
#include <string.h>
2017-05-23 19:35:24 +00:00
/*
Queue:
A storage data structure which follows the rule 'first-in, first-out', and has special functions 'enqueue' and 'dequeue' to manipulate the queue.
*/
2017-10-02 10:40:39 +00:00
/*
Queue constants:
*/
#ifndef QUEUE_SIZE_DEFAULT
#define QUEUE_SIZE_DEFAULT 64
#endif
/*
QUEUE: the queue type for a specific queue.
*/
2017-05-23 19:35:24 +00:00
#define QUEUE TEMPLATE(QUEUE_TYPE,queue)
/*
Queue Structure:
2017-10-02 10:40:39 +00:00
Each queue will contain an array of data, as well as a front, back, and size integer.
2017-05-23 19:35:24 +00:00
*/
typedef struct {
QUEUE_TYPE* data;
2017-10-02 10:40:39 +00:00
int back;//The index after the last element of the queue.
int front;//The index of the first element.
int size;//The size of the data array.
2017-05-23 19:35:24 +00:00
} QUEUE;
2017-10-02 10:40:39 +00:00
/*
Queue Creation:
Creates a new queue with a default size defined above.
*/
QUEUE TEMPLATE(new,QUEUE)(){
QUEUE queue;
queue.front = 0;
queue.back = 0;
queue.size = QUEUE_SIZE_DEFAULT;
queue.data = malloc(queue.size*sizeof(QUEUE_TYPE));
assert(queue.data != NULL);
return queue;
}
/*
Queue deallocation:
Safely deallocates memory assigned to the queue.
*/
void TEMPLATE(free,QUEUE)(QUEUE queue){
free(queue.data);
}
/*
Size of the queue:
returns the size of the queue. (Number of elements in the queue.)
*/
int TEMPLATE(size,QUEUE)(QUEUE queue){
return queue.back-queue.front;
}
/*
Enqueue:
Enqueues an item into the queue.
*/
void TEMPLATE(enqueue,QUEUE)(QUEUE *queue, QUEUE_TYPE item){
//Ensure that enough memory is available.
if (queue->back == queue->size){
queue->data = realloc(queue->data, (queue->size*2)*sizeof(QUEUE_TYPE));
assert(queue->data != NULL);
}
queue->data[queue->back] = item;
queue->back++;
}
/*
Dequeue:
Dequeues an item from the queue.
*/
QUEUE_TYPE TEMPLATE(dequeue,QUEUE)(QUEUE *queue){
QUEUE_TYPE item = queue->data[queue->front];
queue->front++;
//Check to see if it is possible to shrink the array.
if (queue->back - queue->front < queue->size/2){
QUEUE_TYPE* newData = malloc((queue->size/2)*sizeof(QUEUE_TYPE));
int size = queue->back - queue->front;
assert(newData != NULL);
memcpy(newData, queue->data + queue->front, size*sizeof(QUEUE_TYPE));
free(queue->data);
queue->data = newData;
queue->size /= 2;
queue->front = 0;
queue->back = size;
}
return item;
}
/*
Empty:
Returns true if the queue is empty.
*/
int TEMPLATE(empty,QUEUE)(QUEUE queue){
return (queue.back == queue.front);
}
/*
Print:
Prints info about the queue, in well formatted fashion.
*/
void TEMPLATE(print,QUEUE)(QUEUE queue){
printf("Queue: (Items: %d), (Size: %d), (Front: %d), (Back: %d)\n", TEMPLATE(size,QUEUE)(queue), queue.size, queue.front, queue.back);
}
2017-05-23 19:35:24 +00:00
#endif