队列-链式存储

链表实现队列




创建3个文件:queueLinked.h、queueLinked.c、queueLinkedTest.c




queueLinked.h
#ifndef QUEUE_LINKED_H_
#define QUEUE_LINKED_H_

#ifdef __GNUC__
	#define DEPRECATED __attribute__( (deprecated) )
#elif defined(_MSC_VER)
	#define DEPRECATED __declspec( deprecated )
#else
	#define DEPRECATED
#endif

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

#define ADT QueueLinked

// 功能: a与b的比较过程.
// 参数: a, b.
// 返回: a>b返回正数, a

queueLinked.c
#include 
#include 
#include 
#include "queueLinked.h"

// 功能: 打印错误信息后就错误退出程序.
// 参数: expression(错误判断表达式), message(需打印的错误信息).
// 返回: 无.
// 注意: 当表达式 expression 为真时, 才触发.
#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 QueueLinked

typedef struct NodeQueueLinked {
	void *data;
	struct NodeQueueLinked *prev; // 队列头结点的prev指向队头.
	struct NodeQueueLinked *next; // 队列头结点的next指向队尾.
} Node;

ADT *newQueueLinked( void ) {
	ADT *queue = NULL;

	queue = calloc( sizeof(*queue), 1 );
	ERROR_EXIT( !queue, NULL );

	return queue;
}

void *addQueueLinked( ADT *queue, void *data ) {
	Node *n = NULL;

	ERROR_EXIT( !queue, NULL );
	n = malloc( sizeof(*n) );
	ERROR_EXIT( !n, NULL );
	n->data = data;
	n->prev = NULL;
	n->next = queue->next;
	if( queue->next != NULL ) {
		queue->next->prev = n;
	}
	queue->prev = !queue->prev ? n : queue->prev;
	queue->next = n;
	queue->data = ITOP( PTOI( queue->data ) + 1 );

	return data;
}

void *addHeadQueueLinked( ADT *queue, void *data ) {
	Node *n = NULL;

	ERROR_EXIT( !queue, NULL );
	n = malloc( sizeof(*n) );
	ERROR_EXIT( !n, NULL );
	n->data = data;
	n->prev = queue->prev;
	n->next = NULL;
	if( queue->prev != NULL ) {
		queue->prev->next = n;
	}
	queue->prev = n;
	queue->next = !queue->next ? n : queue->next;
	queue->data = ITOP( PTOI( queue->data ) + 1 );

	return data;
}

void *pollQueueLinked( ADT *queue ) {
	void *data = NULL;
	Node *n = NULL;

	ERROR_EXIT( !queue || PTOI( queue->data ) < 1, NULL );
	n = queue->prev;
	if( n->prev != NULL ) {
		n->prev->next = NULL;
	}
	queue->prev = n->prev;
	queue->next = n != queue->next ? queue->next : NULL;
	queue->data = ITOP( PTOI( queue->data ) - 1 );
	data = n->data;
	free( n );

	return data;
}

void *pollTailQueueLinked( ADT *queue ) {
	void *data = NULL;
	Node *n = NULL;

	ERROR_EXIT( !queue || PTOI( queue->data ) < 1, NULL );
	n = queue->next;
	if( n->next != NULL ) {
		n->next->prev = NULL;
	}
	queue->prev = n != queue->prev ? queue->prev : NULL;
	queue->next = n->next;
	queue->data = ITOP( PTOI( queue->data ) - 1 );
	data = n->data;
	free( n );

	return data;
}

void *peekQueueLinked( ADT *queue ) {
	ERROR_EXIT( !queue || PTOI( queue->data ) < 1, NULL );

	return queue->prev->data;
}

void *peekTailQueueLinked( ADT *queue ) {
	ERROR_EXIT( !queue || PTOI( queue->data ) < 1, NULL );

	return queue->next->data;
}

int existQueueLinked( ADT *queue, void *data, CompareFunc *cmp ) {
	Node *n = NULL;

	ERROR_EXIT( !queue || !cmp, NULL );
	for( n = queue->prev; n != NULL; n = n->prev ) {
		if( !cmp( n->data, data ) ) {
			return 1;
		}
	}

	return 0;
}

int32_t findQueueLinked( ADT *queue, void *data, CompareFunc *cmp ) {
	Node *n = NULL;
	int32_t i = 0;

	ERROR_EXIT( !queue || !cmp, NULL );
	for( n = queue->prev; n != NULL; n = n->prev ) {
		if( !cmp( n->data, data ) ) {
			return PTOI( queue->data ) - 1 - i;
		}
		++i;
	}

	return -1;
}

int32_t findTailQueueLinked( ADT *queue, void *data, CompareFunc *cmp ) {
	Node *n = NULL;
	int32_t i = 0;

	ERROR_EXIT( !queue || !cmp, NULL );
	for( n = queue->next; n != NULL; n = n->next ) {
		if( !cmp( n->data, data ) ) {
			return i;
		}
		++i;
	}

	return -1;
}

int32_t sizeQueueLinked( ADT *queue ) {
	ERROR_EXIT( !queue, NULL );

	return PTOI( queue->data );
}

int emptyQueueLinked( ADT *queue ) {
	ERROR_EXIT( !queue, NULL );

	return PTOI( queue->data ) < 1;
}

void reversalQueueLinked( ADT *queue ) {
	Node *p1 = NULL, *p2 = NULL, *p3 = NULL;

	ERROR_EXIT( !queue, NULL );
	queue->prev = queue->next;
	for( p1 = NULL, p2 = queue->next; p2 != NULL; p2 = p3 ) { // 三指针法反转链表.
		p3 = p2->next;
		p2->prev = p3;
		p2->next = p1;
		p1 = p2;
	}
	queue->next = p1;
}

int fullQueueLinked( ADT *queue ) {
	ERROR_EXIT( !queue, NULL );

	return 0;
}

int32_t capacityQueueLinked( ADT *queue ) {
	ERROR_EXIT( !queue, NULL );

	return INT32_MAX;
}

void clearQueueLinked( ADT *queue ) {
	Node *current = NULL, *prev = NULL;

	ERROR_EXIT( !queue, NULL );
	for( current = queue->prev; current != NULL; current = prev ) {
		prev = current->prev;
		free( current );
	}
	queue->data = ITOP( 0 );
}

void delQueueLinked( ADT **queue ) {
	Node *current = NULL, *prev = NULL;

	ERROR_EXIT( !queue, NULL );
	if( !queue ) {
		return;
	}
	for( current = queue[0]->prev; current != NULL; current = prev ) {
		prev = current->prev;
		free( current );
	}
	free( *queue );
	*queue = NULL;
}

queueLinkedTest.c
#include 
#include 
#include 
#include 
#include "queueLinked.h"

// a>b返回正数, a



队列-链式存储_第1张图片

你可能感兴趣的:(队列-链式存储)