数组实现循环队列
创建3个文件:queueArray.h、queueArray.c、queueArrayTest.c
queueArray.h
#ifndef QUEUE_ARRAY_H_
#define 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 QueueArray
// 功能: a与b的比较过程.
// 参数: a, b.
// 返回: a>b返回正数, a<b返回负数, 否则返回0.
// 注意: a不为NULL且b为NULL,返回正数, a为NULL且b不为NULL,返回负数, a与b都为NULL,返回0.
typedef int ( CompareFunc )( const void *a, const void *b );
typedef struct QueueArray ADT;
// 功能: 创建一个新的队列.
// 参数: capacity(队列的最大容量).
// 返回: 一个新的队列.
// 注意: 当 capacity 小于0时,默认为512; 当内存分配失败时,将错误退出程序.
extern ADT *newQueueArray( int32_t capacity );
// 功能: 将用户数据加入到队尾.
// 参数: queue(队列对象的指针), data(用户数据).
// 返回: 被加入到队尾的用户数据.
// 注意: 当 queue 为NULL 或 满队列状态 时, 将错误退出程序.
extern void *addQueueArray( ADT *queue, void *data );
// 功能: 将队头用户数据移除队头.
// 参数: queue(队列对象的指针).
// 返回: 被移除的队头用户数据.
// 注意: 当 queue 为NULL 或 空队列状态 时, 将错误退出程序.
extern void *pollQueueArray( ADT *queue );
// 功能: 偷看队头的用户数据.
// 参数: queue(队列对象的指针).
// 返回: 队头的用户数据.
// 注意: 当 queue 为NULL 或 空队列状态 时, 将错误退出程序.
extern void *peekQueueArray( ADT *queue );
// 功能: 偷看队尾的用户数据.
// 参数: queue(队列对象的指针).
// 返回: 队尾的用户数据.
// 注意: 当 queue 为NULL 或 空队列状态 时, 将错误退出程序.
extern void *peekTailQueueArray( ADT *queue );
// 功能: 队列中所有用户数据中是否包含了data.
// 参数: queue(队列对象的指针), data(需查找的用户数据), cmp(用户自定义比较函数).
// 返回: 包含了data返回1, 否则返回0.
// 注意: 当 queue 为NULL 或 cmp 为NULL 时, 将错误退出程序.
extern int existQueueArray( ADT *queue, void *data, CompareFunc *cmp );
// 功能: 从队头到队尾方向查找data.
// 参数: queue(队列对象的指针), data(需查找的用户数据), cmp(用户自定义比较函数).
// 返回: 队列中包含了data, 返回data所在位置, 否则返回-1.
// 注意: 当 queue 为NULL 或 cmp 为NULL 时, 将错误退出程序.
extern int32_t findQueueArray( ADT *queue, void *data, CompareFunc *cmp );
// 功能: 从队尾到队头方向查找data.
// 参数: queue(队列对象的指针), data(需查找的用户数据), cmp(用户自定义比较函数).
// 返回: 队列中包含了data, 返回data所在位置, 否则返回-1.
// 注意: 当 queue 为NULL 或 cmp 为NULL 时, 将错误退出程序.
extern int32_t findTailQueueArray( ADT *queue, void *data, CompareFunc *cmp );
// 功能: 队列实际已使用大小.
// 参数: queue(队列对象的指针).
// 返回: 队列实际已使用大小.
// 注意: 当 queue 为NULL 时, 将错误退出程序.
extern int32_t sizeQueueArray( ADT *queue );
// 功能: 空队列状态.
// 参数: queue(队列对象的指针).
// 返回: 是空队列返回1, 否则返回0.
// 注意: 当 queue 为NULL 时, 将错误退出程序.
extern int emptyQueueArray( ADT *stsack );
// 功能: 满队列状态.
// 参数: queue(队列对象的指针).
// 返回: 是满队列返回1, 否则返回0.
// 注意: 当 queue 为NULL 时, 将错误退出程序.
extern int fullQueueArray( ADT *queue );
// 功能: 队列最大容量.
// 参数: queue(队列对象的指针).
// 返回: 队列最大容量.
// 注意: 当 queue 为NULL 时, 将错误退出程序.
extern int32_t capacityQueueArray( ADT *queue );
// 功能: 清空队列.
// 参数: queue(队列对象的指针).
// 返回: 无.
// 注意: 当 queue 为NULL 时, 将错误退出程序.
extern void clearQueueArray( ADT *queue );
// 功能: 销毁队列.
// 参数: queue(存放队列对象的指针的指针).
// 返回: 无.
// 注意: 当 queue 为NULL 时, 将错误退出程序.
extern void delQueueArray( ADT **queue );
#undef ADT
#endif
queueArray.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "queueArray.h"
// 功能: 打印错误信息后就错误退出程序.
// 参数: expression(错误判断表达式), message(需打印的错误信息).
// 返回: 无.
// 注意: 当表达式 expression 为真时, 才触发.
#define ERROR_EXIT( expression, message )
if( (expression) ) {
fprintf( stderr, "
error location: file = %s, func = %s, line = %d.
",
__FILE__, __func__, __LINE__ );
fprintf( stderr, "error message: %s%s.
a",
(message) != NULL ? (message) : __func__,
(message) != NULL ? "" : " function error" );
exit( EXIT_FAILURE );
}
#define ADT QueueArray
struct QueueArray {
int32_t capacity;
int32_t size;
int32_t head;
void *array[0];
};
ADT *newQueueArray( 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 *addQueueArray( QueueArray *queue, void *data ) {
ERROR_EXIT( !queue || queue->size >= queue->capacity, NULL );
queue->array[(queue->head + queue->size++) % queue->capacity] = data;
return data;
}
void *pollQueueArray( QueueArray *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 *peekQueueArray( QueueArray *queue ) {
ERROR_EXIT( !queue || queue->size < 1, NULL );
return queue->array[queue->head];
}
void *peekTailQueueArray( QueueArray *queue ) {
ERROR_EXIT( !queue || queue->size < 1, NULL );
return queue->array[(queue->head + queue->size - 1) % queue->capacity];
}
int existQueueArray( QueueArray *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 findQueueArray( QueueArray *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 findTailQueueArray( QueueArray *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 sizeQueueArray( QueueArray *queue ) {
ERROR_EXIT( !queue, NULL );
return queue->size;
}
int emptyQueueArray( QueueArray *queue ) {
ERROR_EXIT( !queue, NULL );
return queue->size < 1;
}
int fullQueueArray( QueueArray *queue ) {
ERROR_EXIT( !queue, NULL );
return queue->size >= queue->capacity;
}
int32_t capacityQueueArray( QueueArray *queue ) {
ERROR_EXIT( !queue, NULL );
return queue->capacity;
}
void clearQueueArray( QueueArray *queue ) {
ERROR_EXIT( !queue, NULL );
queue->size = 0;
queue->head = 0;
}
void delQueueArray( QueueArray **queue ) {
ERROR_EXIT( !queue, NULL );
free( *queue );
*queue = NULL;
}
queueArrayTest.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include "queueArray.h"
// a>b返回正数, a<b返回负数, 否则返回0.
static int cmp( const void *a, const void *b ) {
return *(int32_t *) a - *(int32_t *) b;
}
int main( int argc, char *argv[] ) {
char *tf[] = {"false", "true"};
int32_t *a = NULL, n = 0;
int32_t i = 0, k = 0;
QueueArray *q = NULL;
srand( time( NULL ) );
printf( "please input array length: n = " );
scanf( "%d%*c", &n );
printf( "
" );
a = malloc( sizeof(*a) * n );
for( i = 0; i < n; ++i ) {
a[i] = rand() % 322;
//a[i] = 1;
}
printf( "&q = %p, q = %p
", &q, q );
q = newQueueArray( n );
printf( "new: &q = %p, q = %p
", &q, q );
printf( "peek = %d
", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekQueueArray( q ) );
printf( "peekTail = %d
", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekTailQueueArray( q ) );
printf( "size = %d
", sizeQueueArray( q ) );
printf( "empty = %s
", tf[emptyQueueArray( q )]);
printf( "full = %s
", tf[fullQueueArray( q )] );
printf( "capacity = %d
", capacityQueueArray( q ) );
printf( "
" );
printf( "add all: [" );
for( i = 0; i < n; ++i ) {
printf( ", %5d", *(int32_t *) addQueueArray( q, &a[i] ) );
}
printf( "]
" );
printf( "peek = %d
", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekQueueArray( q ) );
printf( "peekTail = %d
", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekTailQueueArray( q ) );
printf( "size = %d
", sizeQueueArray( q ) );
printf( "empty = %s
", tf[emptyQueueArray( q )] );
printf( "full = %s
", tf[fullQueueArray( q )] );
printf( "capacity = %d
", capacityQueueArray( q ) );
printf( "
" );
//k = a[0];
k = rand();
printf( "exist &k(%d) = %s
", k, tf[existQueueArray( q, &k, cmp )] );
printf( "
" );
k = a[0];
//k = rand();
printf( "find &k(%d) = %d
", k, findQueueArray( q, &k, cmp ) );
printf( "
" );
//k = a[0];
k = rand();
printf( "findTile &k(%d) = %d
", k, findTailQueueArray( q, &k, cmp ) );
printf( "
" );
printf( "poll all: [" );
while( !emptyQueueArray( q ) ) {
printf( ", %5d", *(int32_t *) pollQueueArray( q ) );
//printf( "peek = %d
", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekQueueArray( q ) );
//printf( "peekTail = %d
", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekTailQueueArray( q ) );
//printf( "size = %d
", sizeQueueArray( q ) );
//printf( "empty = %s
", tf[emptyQueueArray( q )] );
//printf( "full = %s
", tf[fullQueueArray( q )] );
//printf( "capacity = %d
", capacityQueueArray( q ) );
//printf( "
" );
}
printf( "]
" );
printf( "peek = %d
", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekQueueArray( q ) );
printf( "peekTail = %d
", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekTailQueueArray( q ) );
printf( "size = %d
", sizeQueueArray( q ) );
printf( "empty = %s
", tf[emptyQueueArray( q )] );
printf( "full = %s
", tf[fullQueueArray( q )] );
printf( "capacity = %d
", capacityQueueArray( q ) );
printf( "
" );
delQueueArray( &q );
printf( "del: &q = %p, q = %p
", &q, q );
return EXIT_SUCCESS;
}
