循環隊列-順序存儲

數組實現循環隊列




建立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"

#define ADT QueueArray

// 功能: 打印錯誤信息後就錯誤退出程序.
// 參數: expression(錯誤判斷表達式), message(需打印的錯誤信息).
// 返回: 無.
// 注意: 當expression爲真時,才觸發.
#define ERROR_EXIT( expression, message )                 \
if( (expression) ) {                                      \
	fprintf( stderr, "\nerror location: %s, %s, %u.\n",   \
	                 __FILE__, __func__, __LINE__ );      \
	fprintf( stderr, "error message: %s.\n",              \
	                 !(message) ? __func__ : (message) ); \
	exit( EXIT_FAILURE );                                 \
}

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 || !data || !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( "\n" );

	a = malloc( sizeof(*a) * n );
	for( i = 0; i < n; ++i ) {
		a[i] = rand() % 322;
		//a[i] = 1;
	}

	printf( "&q = %p, q = %p\n", &q, q );
	q = newQueueArray( n );
	printf( "new: &q = %p, q = %p\n", &q, q );

	printf( "peek       = %d\n", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekQueueArray( q ) );
	printf( "peekTail = %d\n", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekTailQueueArray( q ) );
	printf( "size     = %d\n", sizeQueueArray( q ) );
	printf( "empty = %s\n", tf[emptyQueueArray( q )]);
	printf( "full  = %s\n", tf[fullQueueArray( q )] );
	printf( "capacity = %d\n", capacityQueueArray( q ) );
	printf( "\n" );

	printf( "add all: [" );
	for( i = 0; i < n; ++i ) {
		printf( ", %5d", *(int32_t *) addQueueArray( q, &a[i] ) );
	}
	printf( "]\n" );

	printf( "peek       = %d\n", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekQueueArray( q ) );
	printf( "peekTail = %d\n", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekTailQueueArray( q ) );
	printf( "size     = %d\n", sizeQueueArray( q ) );
	printf( "empty = %s\n", tf[emptyQueueArray( q )] );
	printf( "full  = %s\n", tf[fullQueueArray( q )] );
	printf( "capacity = %d\n", capacityQueueArray( q ) );
	printf( "\n" );

	//k = a[0];
	k = rand();
	printf( "exist &k(%d) = %s\n", k, tf[existQueueArray( q, &k, cmp )] );
	printf( "\n" );

	k = a[0];
	//k = rand();
	printf( "find &k(%d) = %d\n", k, findQueueArray( q, &k, cmp ) );
	printf( "\n" );

	//k = a[0];
	k = rand();
	printf( "findTile &k(%d) = %d\n", k, findTailQueueArray( q, &k, cmp ) );
	printf( "\n" );

	printf( "poll all:  [" );
	while( !emptyQueueArray( q ) ) {
		printf( ", %5d", *(int32_t *) pollQueueArray( q ) );
		//printf( "peek       = %d\n", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekQueueArray( q ) );
		//printf( "peekTail = %d\n", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekTailQueueArray( q ) );
		//printf( "size     = %d\n", sizeQueueArray( q ) );
		//printf( "empty = %s\n", tf[emptyQueueArray( q )] );
		//printf( "full  = %s\n", tf[fullQueueArray( q )] );
		//printf( "capacity = %d\n", capacityQueueArray( q ) );
		//printf( "\n" );
	}
	printf( "]\n" );

	printf( "peek       = %d\n", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekQueueArray( q ) );
	printf( "peekTail = %d\n", emptyQueueArray( q ) ? INT32_MIN : *(int32_t *) peekTailQueueArray( q ) );
	printf( "size     = %d\n", sizeQueueArray( q ) );
	printf( "empty = %s\n", tf[emptyQueueArray( q )] );
	printf( "full  = %s\n", tf[fullQueueArray( q )] );
	printf( "capacity = %d\n", capacityQueueArray( q ) );
	printf( "\n" );

	delQueueArray( &q );
	printf( "del: &q = %p, q = %p\n", &q, q );

	return EXIT_SUCCESS;
}



相關文章
相關標籤/搜索