• 循环双端队列-顺序存储


    数组实现循环双端队列




    创建3个文件: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
    
    // 功能: 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 DoubleEndedQueueArray DequeArray;
    
    // 功能: 创建一个新的双端队列.
    // 参数: capacity(双端队列的最大容量).
    // 返回: 一个新的双端队列.
    // 注意: 当 capacity 小于0时,默认为512; 当内存分配失败时,将错误退出程序.
    extern ADT *newDequeArray( int32_t capacity );
    
    // 功能: 将用户数据加入到队尾.
    // 参数: queue(双端队列对象的指针), data(用户数据).
    // 返回: 被加入到队尾的用户数据.
    // 注意: 当 queue 为NULL 或 满双端队列状态 时, 将错误退出程序.
    extern void *addDequeArray( ADT *queue, void *data );
    
    // 功能: 将用户数据加入到队头.
    // 参数: queue(双端队列对象的指针), data(用户数据).
    // 返回: 被加入到队头的用户数据.
    // 注意: 当 queue 为NULL 或 满双端队列状态 时, 将错误退出程序.
    extern void *addHeadDequeArray( ADT *queue, void *data );
    
    // 功能: 将队头用户数据移除队头.
    // 参数: queue(双端队列对象的指针).
    // 返回: 被移除的队头用户数据.
    // 注意: 当 queue 为NULL 或 空双端队列状态 时, 将错误退出程序.
    extern void *pollDequeArray( ADT *queue );
    
    // 功能: 将队尾用户数据移除队头.
    // 参数: queue(双端队列对象的指针).
    // 返回: 被移除的队尾用户数据.
    // 注意: 当 queue 为NULL 或 空双端队列状态 时, 将错误退出程序.
    extern void *pollTailDequeArray( ADT *queue );
    
    // 功能: 偷看队头的用户数据.
    // 参数: queue(双端队列对象的指针).
    // 返回: 队头的用户数据.
    // 注意: 当 queue 为NULL 或 空双端队列状态 时, 将错误退出程序.
    extern void *peekDequeArray( ADT *queue );
    
    // 功能: 偷看队尾的用户数据.
    // 参数: queue(双端队列对象的指针).
    // 返回: 队尾的用户数据.
    // 注意: 当 queue 为NULL 或 空双端队列状态 时, 将错误退出程序.
    extern void *peekTailDequeArray( ADT *queue );
    
    
    // 功能: 双端队列中所有用户数据中是否包含了data.
    // 参数: queue(双端队列对象的指针), data(需查找的用户数据), cmp(用户自定义比较函数).
    // 返回: 包含了data返回1, 否则返回0.
    // 注意: 当 queue 为NULL 或 cmp 为NULL 时, 将错误退出程序.
    extern int existDequeArray( ADT *queue, void *data, CompareFunc *cmp );
    
    // 功能: 从队头到队尾方向查找data.
    // 参数: queue(双端队列对象的指针), data(需查找的用户数据), cmp(用户自定义比较函数).
    // 返回: 双端队列中包含了data, 返回data所在位置, 否则返回-1.
    // 注意: 当 queue 为NULL 或 cmp 为NULL 时, 将错误退出程序.
    extern int32_t findDequeArray( ADT *queue, void *data, CompareFunc *cmp );
    
    // 功能: 从队尾到队头方向查找data.
    // 参数: queue(双端队列对象的指针), data(需查找的用户数据), cmp(用户自定义比较函数).
    // 返回: 双端队列中包含了data, 返回data所在位置, 否则返回-1.
    // 注意: 当 queue 为NULL 或 cmp 为NULL 时, 将错误退出程序.
    extern int32_t findTailDequeArray( ADT *queue, void *data, CompareFunc *cmp );
    
    // 功能: 双端队列实际已使用大小.
    // 参数: queue(双端队列对象的指针).
    // 返回: 双端队列实际已使用大小.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    extern int32_t sizeDequeArray( ADT *queue );
    
    // 功能: 空双端队列状态.
    // 参数: queue(双端队列对象的指针).
    // 返回: 是空双端队列返回1, 否则返回0.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    extern int emptyDequeArray( ADT *stsack );
    
    // 功能: 满双端队列状态.
    // 参数: queue(双端队列对象的指针).
    // 返回: 是满双端队列返回1, 否则返回0.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    extern int fullDequeArray( ADT *queue );
    
    // 功能: 双端队列最大容量.
    // 参数: queue(双端队列对象的指针).
    // 返回: 双端队列最大容量.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    extern int32_t capacityDequeArray( ADT *queue );
    
    // 功能: 清空双端队列.
    // 参数: queue(双端队列对象的指针).
    // 返回: 无.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    extern void clearDequeArray( ADT *queue );
    
    // 功能: 销毁双端队列.
    // 参数: queue(存放双端队列对象的指针的指针).
    // 返回: 无.
    // 注意: 当 queue 为NULL 时, 将错误退出程序.
    extern void delDequeArray( ADT **queue );
    
    #undef ADT
    
    #endif
    

    doubleEndedQueueArray.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include "doubleEndedQueueArray.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 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 <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <time.h>
    #include "doubleEndedQueueArray.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;
    	DequeArray *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 = newDequeArray( n );
    	printf( "new: &q = %p, q = %p
    ", &q, q );
    
    	printf( "peek       = %d
    ", emptyDequeArray( q ) ? INT32_MIN : *(int32_t *) peekDequeArray( q ) );
    	printf( "peekTail = %d
    ", emptyDequeArray( q ) ? INT32_MIN : *(int32_t *) peekTailDequeArray( q ) );
    	printf( "size     = %d
    ", sizeDequeArray( q ) );
    	printf( "empty = %s
    ", tf[emptyDequeArray( q )]);
    	printf( "full  = %s
    ", tf[fullDequeArray( q )] );
    	printf( "capacity = %d
    ", capacityDequeArray( q ) );
    	printf( "
    " );
    
    	for( i = 0; i < n; ++i ) {
    		if( i & 1 ) {
    			printf( "add: %d
    ", *(int32_t *) addDequeArray( q, &a[i] ) );
    		} else {
    			printf( "addHead: %d
    ", *(int32_t *) addHeadDequeArray( q, &a[i] ) );
    		}
    	}
    	printf( "
    " );
    
    	printf( "peek       = %d
    ", emptyDequeArray( q ) ? INT32_MIN : *(int32_t *) peekDequeArray( q ) );
    	printf( "peekTail = %d
    ", emptyDequeArray( q ) ? INT32_MIN : *(int32_t *) peekTailDequeArray( q ) );
    	printf( "size     = %d
    ", sizeDequeArray( q ) );
    	printf( "empty = %s
    ", tf[emptyDequeArray( q )] );
    	printf( "full  = %s
    ", tf[fullDequeArray( q )] );
    	printf( "capacity = %d
    ", capacityDequeArray( q ) );
    	printf( "
    " );
    
    	//k = a[0];
    	k = rand();
    	printf( "exist &k(%d) = %s
    ", k, tf[existDequeArray( q, &k, cmp )] );
    	printf( "
    " );
    
    	k = a[0];
    	//k = rand();
    	printf( "find &k(%d) = %d
    ", k, findDequeArray( q, &k, cmp ) );
    	printf( "
    " );
    
    	//k = a[0];
    	k = rand();
    	printf( "findTile &k(%d) = %d
    ", k, findTailDequeArray( q, &k, cmp ) );
    	printf( "
    " );
    
    	for( i = 0; !emptyDequeArray( q ); ++i ) {
    		if( i & 1 ) {
    			printf( "poll: %d
    ", *(int32_t *) pollDequeArray( q ) );
    		} else {
    			printf( "pollTail: %d
    ", *(int32_t *) pollTailDequeArray( q ) );
    		}
    		//printf( "peek       = %d
    ", emptyDequeArray( q ) ? INT32_MIN : *(int32_t *) peekDequeArray( q ) );
    		//printf( "peekTail = %d
    ", emptyDequeArray( q ) ? INT32_MIN : *(int32_t *) peekTailDequeArray( q ) );
    		//printf( "size     = %d
    ", sizeDequeArray( q ) );
    		//printf( "empty = %s
    ", tf[emptyDequeArray( q )] );
    		//printf( "full  = %s
    ", tf[fullDequeArray( q )] );
    		//printf( "capacity = %d
    ", capacityDequeArray( q ) );
    		//printf( "
    " );
    	}
    	printf( "
    " );
    
    	printf( "peek       = %d
    ", emptyDequeArray( q ) ? INT32_MIN : *(int32_t *) peekDequeArray( q ) );
    	printf( "peekTail = %d
    ", emptyDequeArray( q ) ? INT32_MIN : *(int32_t *) peekTailDequeArray( q ) );
    	printf( "size     = %d
    ", sizeDequeArray( q ) );
    	printf( "empty = %s
    ", tf[emptyDequeArray( q )] );
    	printf( "full  = %s
    ", tf[fullDequeArray( q )] );
    	printf( "capacity = %d
    ", capacityDequeArray( q ) );
    	printf( "
    " );
    
    	delDequeArray( &q );
    	printf( "del: &q = %p, q = %p
    ", &q, q );
    
    	return EXIT_SUCCESS;
    }
    



  • 相关阅读:
    Windows桌面开发之窗口
    imes系统完善
    Dos.ORM简单说明
    C# 调用C++ dll的方法
    Windows10内置Linux子系统(WSL)Vmmem内存占用过大问题
    Docker 常用命令
    Typora 激活
    C# LINQ去重
    Windows10内置Linux子系统(WSL)映射本地盘符
    00-mORMot安装
  • 原文地址:https://www.cnblogs.com/hujunxiang98/p/12880217.html
Copyright © 2020-2023  润新知