zoukankan      html  css  js  c++  java
  • 队列-链式存储

    链表实现队列




    创建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<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 NodeQueueLinked QueueLinked;
    
    // 功能: 创建新的队列.
    // 参数: 无.
    // 返回: 新的队列.
    // 注意: 当内存分配失败时,将错误退出程序.
    extern ADT *newQueueLinked( void );
    
    // 功能: 将用户数据加入到队尾.
    // 参数: queue(队列对象的指针), data(用户数据).
    // 返回: 被加入到队尾的用户数据.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    extern void *addQueueLinked( ADT *queue, void *data );
    
    // 功能: 将用户数据加入到队头.
    // 参数: queue(队列对象的指针), data(用户数据).
    // 返回: 被加入到队头的用户数据.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    extern void *addHeadQueueLinked( ADT *queue, void *data );
    
    // 功能: 移除队头用户数据.
    // 参数: queue(队列对象的指针).
    // 返回: 被移除的队头的用户数据.
    // 注意: 当 queue 为NULL 或 空队列状态 时, 将错误退出程序.
    extern void *pollQueueLinked( ADT *queue );
    
    // 功能: 移除队尾用户数据.
    // 参数: queue(队列对象的指针).
    // 返回: 被移除的队尾的用户数据.
    // 注意: 当 queue 为NULL 或 空队列状态 时, 将错误退出程序.
    extern void *pollTailQueueLinked( ADT *queue );
    
    // 功能: 偷看队头的用户数据.
    // 参数: queue(队列对象的指针).
    // 返回: 队头的用户数据.
    // 注意: 当 queue 为NULL 或 空队列状态 时, 将错误退出程序.
    extern void *peekQueueLinked( ADT *queue );
    
    // 功能: 偷看队尾的用户数据.
    // 参数: queue(队列对象的指针).
    // 返回: 队尾的用户数据.
    // 注意: 当 queue 为NULL 或 空队列状态 时, 将错误退出程序.
    extern void *peekTailQueueLinked( ADT *queue );
    
    // 功能: 队列中所有用户数据中是否包含了data.
    // 参数: queue(队列对象的指针), data(需查找的用户数据), cmp(比较函数的指针).
    // 返回: 包含data返回1, 否则返回0.
    // 注意: 当 queue 为NULL 或 cmp 为NULL 时, 将错误退出程序.
    extern int existQueueLinked( ADT *queue, void *data, CompareFunc *cmp );
    
    // 功能: 从队头至队尾方向查找data.
    // 参数: queue(队列对象的指针), data(需查找的用户数据), cmp(比较函数的指针).
    // 返回: 包含data, 返回data所在位置, 否则返回-1.
    // 注意: 当 queue 为NULL 或 cmp 为NULL 时, 将错误退出程序.
    extern int32_t findQueueLinked( ADT *queue, void *data, CompareFunc *cmp );
    
    // 功能: 从队尾至队头方向查找data.
    // 参数: queue(队列对象的指针), data(需查找的用户数据), cmp(比较函数的指针).
    // 返回: 包含data, 返回data所在位置, 否则返回-1.
    // 注意: 当 queue 为NULL 或 cmp 为NULL 时, 将错误退出程序.
    extern int32_t findTailQueueLinked( ADT *queue, void *data, CompareFunc *cmp );
    
    // 功能: 队列实际已使用大小.
    // 参数: queue(队列对象的指针).
    // 返回: 队列实际已使用大小.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    extern int32_t sizeQueueLinked( ADT *queue );
    
    // 功能: 空队列状态.
    // 参数: queue(队列对象的指针).
    // 返回: 是空队列返回1, 否则返回0.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    extern int emptyQueueLinked( ADT *stsack );
    
    // 功能: 反转队列.
    // 参数: queue(队列对象的指针).
    // 返回: 无.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    extern void reversalQueueLinked( ADT *queue );
    
    // 功能: 满队列状态.
    // 参数: queue(队列对象的指针).
    // 返回: 是满队列返回1, 否则返回0.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    // 被弃用的函数.
    extern DEPRECATED int fullQueueLinked( ADT *queue );
    
    // 功能: 队列最大容量.
    // 参数: queue(队列对象的指针).
    // 返回: 队列最大容量.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    // 被弃用的函数.
    extern DEPRECATED int32_t capacityQueueLinked( ADT *queue );
    
    // 功能: 清空队列.
    // 参数: queue(队列对象的指针).
    // 返回: 无.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    extern void clearQueueLinked( ADT *queue );
    
    // 功能: 销毁队列.
    // 参数: queue(存放队列对象的指针的指针).
    // 返回: 无.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    extern void delQueueLinked( ADT **queue );
    
    #undef ADT
    
    #endif
    

    queueLinked.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include "queueLinked.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 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 <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <time.h>
    #include "queueLinked.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;
    	QueueLinked *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 = newQueueLinked();
    	printf( "new: &q = %p, q = %p
    ", &q, q );
    
    	printf( "peek       = %d
    ", emptyQueueLinked( q ) ? INT32_MIN : *(int32_t *) peekQueueLinked( q ) );
    	printf( "peekTail = %d
    ", emptyQueueLinked( q ) ? INT32_MIN : *(int32_t *) peekTailQueueLinked( q ) );
    	printf( "size     = %d
    ", sizeQueueLinked( q ) );
    	printf( "empty = %s
    ", tf[emptyQueueLinked( q )]);
    	printf( "
    " );
    
    	for( i = 0; i < n; ++i ) {
    		#if 1
    		printf( "add: %4d
    ", *(int32_t *) addQueueLinked( q, &a[i] ) );
    		#else
    		printf( "addHead: %4d
    ", *(int32_t *) addHeadQueueLinked( q, &a[i] ) );
    		#endif
    	}
    	printf( "
    " );
    
    	printf( "peek       = %d
    ", emptyQueueLinked( q ) ? INT32_MIN : *(int32_t *) peekQueueLinked( q ) );
    	printf( "peekTail = %d
    ", emptyQueueLinked( q ) ? INT32_MIN : *(int32_t *) peekTailQueueLinked( q ) );
    	printf( "size     = %d
    ", sizeQueueLinked( q ) );
    	printf( "empty = %s
    ", tf[emptyQueueLinked( q )] );
    	printf( "
    " );
    
    	k = a[0];
    	//k = rand();
    	//printf( "exist &k(%d) = %s
    ", k, tf[existQueueLinked( q, &k, cmp )] );
    	printf( "
    " );
    
    	k = a[0];
    	printf( "add: %d
    ", *(int32_t *) addQueueLinked( q, &k ) );
    	//k = rand();
    	printf( "find &k(%d) = %d
    ", k, findQueueLinked( q, &k, cmp ) );
    	printf( "
    " );
    
    	k = a[0];
    	//k = rand();
    	printf( "add: %d
    ", *(int32_t *) addQueueLinked( q, &k ) );
    	printf( "findTile &k(%d) = %d
    ", k, findTailQueueLinked( q, &k, cmp ) );
    	printf( "
    " );
    
    	//reversalQueueLinked( q ); // 反转队列.
    
    	while( !emptyQueueLinked( q ) ) {
    		#if 1
    		printf( "poll: %4d
    ", *(int32_t *) pollQueueLinked( q ) );
    		#else
    		printf( "pollTail: %4d
    ", *(int32_t *) pollTailQueueLinked( q ) );
    		#endif
    		printf( "peek       = %d
    ", emptyQueueLinked( q ) ? INT32_MIN : *(int32_t *) peekQueueLinked( q ) );
    		printf( "peekTail = %d
    ", emptyQueueLinked( q ) ? INT32_MIN : *(int32_t *) peekTailQueueLinked( q ) );
    		printf( "size     = %d
    ", sizeQueueLinked( q ) );
    		printf( "
    " );
    	}
    	printf( "
    " );
    
    	printf( "peek       = %d
    ", emptyQueueLinked( q ) ? INT32_MIN : *(int32_t *) peekQueueLinked( q ) );
    	printf( "peekTail = %d
    ", emptyQueueLinked( q ) ? INT32_MIN : *(int32_t *) peekTailQueueLinked( q ) );
    	printf( "size     = %d
    ", sizeQueueLinked( q ) );
    	printf( "empty = %s
    ", tf[emptyQueueLinked( q )] );
    	printf( "
    " );
    
    	delQueueLinked( &q );
    	printf( "del: &q = %p, q = %p
    ", &q, q );
    
    	return EXIT_SUCCESS;
    }
    



  • 相关阅读:
    Laravel学习之旅(一)
    telnet模拟邮件发送
    学习CodeIgniter框架之旅(二)继承自定义类
    学习CodeIgniter框架之旅(一)自定义模板目录
    MySQL主从复制实现
    coreseek增量索引
    锁(MySQL篇)—之MyISAM表锁

    php文件锁
    进程与线程
  • 原文地址:https://www.cnblogs.com/hujunxiang98/p/12884875.html
Copyright © 2011-2022 走看看