Circular double ended queue sequential storage

Time:2020-11-29

Array implementation of circular double ended queue


Create 3 files: doubleendedqueuearray. H, doubleendedqueuearray. C, doubleendedqueuearraytest. C


doubleEndedQueueArray.h
#ifndef DOUBLE_ENDED_QUEUE_ARRAY_H_
#define DOUBLE_ENDED_QUEUE_ARRAY_H_

#ifndef PTOI
#define PTOI( p ) ((int32_t)(int64_t)(p))
#endif
#ifndef ITOP
#define ITOP( i ) ((void *)(int64_t)(i))
#endif

#define ADT DequeArray

//Function: the process of comparison between a and B
//Parameters: A, B
//Return: a > B returns a positive number, a

doubleEndedQueueArray.c
#include 
#include 
#include 
#include "doubleEndedQueueArray.h"


//Function: print the error message and exit the program
//Parameters: expression (error judgment expression), message (error message to be printed)
//Return: none
//Note: only triggered when expression is true
#define ERROR_EXIT( expression, message )                                    \
if( (expression) ) {                                                         \
	fprintf( stderr, "\nerror location: file = %s, func = %s, line = %d.\n", \
	                       __FILE__, __func__, __LINE__ );                   \
	fprintf( stderr, "error  message: %s%s.\n\a",                            \
	                       (message) != NULL ? (message) : __func__,         \
		                   (message) != NULL ? "" : " function error" );     \
	exit( EXIT_FAILURE );                                                    \
}

#define ADT DequeArray


struct DoubleEndedQueueArray {
	int32_t capacity;
	int32_t size;
	int32_t head;
	void *array[0];
};


ADT *newDequeArray( int32_t capacity ) {
	ADT *queue = NULL;

	capacity = capacity < 0 ? 512 : capacity;
	queue = malloc( sizeof(*queue) + sizeof(queue->array[0]) * capacity );
	ERROR_EXIT( !queue, NULL );
	queue->capacity = capacity;
	queue->size = 0;
	queue->head = 0;

	return queue;
}

void *addDequeArray( DequeArray *queue, void *data ) {
	ERROR_EXIT( !queue || queue->size >= queue->capacity, NULL );
	queue->array[(queue->head + queue->size++) % queue->capacity] = data;

	return data;
}

void *addHeadDequeArray( DequeArray *queue, void *data ) {
	ERROR_EXIT( !queue || queue->size >= queue->capacity, NULL );
	queue->head = (queue->head - 1 + queue->capacity) % queue->capacity;
	queue->array[queue->head] = data;
	++queue->size;

	return data;
}

void *pollDequeArray( DequeArray *queue ) {
	void *data = NULL;

	ERROR_EXIT( !queue || queue->size < 1, NULL );
	data = queue->array[queue->head];
	queue->head = (queue->head + 1) % queue->capacity;
	--queue->size;

	return data;
}

void *pollTailDequeArray( DequeArray *queue ) {
	void *data = NULL;

	ERROR_EXIT( !queue || queue->size < 1, NULL );
	data = queue->array[(--queue->size + queue->head) % queue->capacity];

	return data;
}

void *peekDequeArray( DequeArray *queue ) {
	ERROR_EXIT( !queue || queue->size < 1, NULL );

	return queue->array[queue->head];
}

void *peekTailDequeArray( DequeArray *queue ) {
	ERROR_EXIT( !queue || queue->size < 1, NULL );

	return queue->array[(queue->head + queue->size - 1) % queue->capacity];
}

int existDequeArray( DequeArray *queue, void *data, CompareFunc *cmp ) {
	ERROR_EXIT( !queue || !cmp, NULL );

	for( int32_t i = 0; i < queue->size; ++i ) {
		if( !cmp( queue->array[(queue->head + i) % queue->capacity], data ) ) {
			return 1;
		}
	}

	return 0;
}

int32_t findDequeArray( DequeArray *queue, void *data, CompareFunc *cmp ) {
	int32_t i = 0, j = 0;

	ERROR_EXIT( !queue || !cmp, NULL );
	for( i = 0; i < queue->size; ++i ) {
		j = (queue->head + i) % queue->capacity;
		if( !cmp( queue->array[j], data ) ) {
			return j;
		}
	}

	return -1;
}

int32_t findTailDequeArray( DequeArray *queue, void *data, CompareFunc *cmp ) {
	int32_t i = 0, j = 0;

	ERROR_EXIT( !queue || !cmp, NULL );
	for( i = queue->size - 1; i >= 0; --i ) {
		j = (queue->head + i) % queue->capacity;
		if( !cmp( queue->array[j], data ) ) {
			return j;
		}
	}

	return -1;
}

int32_t sizeDequeArray( DequeArray *queue ) {
	ERROR_EXIT( !queue, NULL );

	return queue->size;
}

int emptyDequeArray( DequeArray *queue ) {
	ERROR_EXIT( !queue, NULL );

	return queue->size < 1;
}

int fullDequeArray( DequeArray *queue ) {
	ERROR_EXIT( !queue, NULL );

	return queue->size >= queue->capacity;
}

int32_t capacityDequeArray( DequeArray *queue ) {
	ERROR_EXIT( !queue, NULL );

	return queue->capacity;
}

void clearDequeArray( DequeArray *queue ) {
	ERROR_EXIT( !queue, NULL );

	queue->size = 0;
	queue->head = 0;
}

void delDequeArray( DequeArray **queue ) {
	ERROR_EXIT( !queue, NULL );
	free( *queue );
	*queue = NULL;
}

doubleEndedQueueArrayTest.c
#include 
#include 
#include 
#include 
#include "doubleEndedQueueArray.h"


//A > B returns a positive number