数据结构 --- 顺序队列(C语言实现)

目录

一、队列基础知识

二、顺序队列数据结构

三、顺序队列函数声明

四、创建顺序队列

1、队列头部动态创建

2、队列头部静态创建

五、出队列

六、入队列

七、队列删除

八、队列销毁

九、验证程序


一、队列基础知识

队列跟栈类似都是“操作受限”的线性表,只不过队列是先进先出结构,队列也有两个基本的操作:入队 enqueue(),放一个数据到队列尾部;出队 dequeue(),从队列头部取一个元素。根据实现方式不同,也可以分为两种:使用数组来实现的顺序队列,和使用链表来实现的链式队列

对于栈来说,我们只需要一个栈顶指针就可以了。但是队列需要两个指针:一个是 head 指针,指向队头;一个是 tail 指针,指向队尾;

在数组实现队列的时候,会有数据搬移操作,要想解决数据搬移的问题,我们就需要像环一样的循环队列。那么如何判断循环队列满和空呢? 如下【右图】会发现:

1、队列满时:head = tail,队列空时:(tail+1)%n = head,这样的话循环队列会浪费一个数组的存储空间。

2、但如果用size来表示队列的总大小,num来记录队列的当前元素个数,则可以这样判断:队列满时:num = size,队列空时:num = 0,这样就能将队列全部空间用来存储数据,这也是最常用的做法

二、顺序队列数据结构

#define ARRAY_QUEUE_SIZE(pqueue)     (pqueue->size)
#define ARRAY_QUEUE_NUM(pqueue)      (pqueue->used)
#define ARRAY_QUEUE_IS_EMPTY(pqueue) (pqueue->num == 0)
#define ARRAY_QUEUE_IS_FULL(pqueue)  (pqueue->num == pqueue->size)

struct array_queue
{
	int size; /* queue total size */
	int num;  /* queue used size rang:1-(size-1) */
	int head; /* points to the location where the next dequeue data store */
	int tail; /* points to the location where the next enqueue data store */
	int tpsz; /* data type size */
	void *p;  /* queue space */
};

三、顺序队列函数声明

extern struct array_queue* array_queue_creat(int size, int tpsz);
extern int array_queue_init   (struct array_queue *queue, int size, int tpsz);
extern int array_queue_empty  (struct array_queue *queue);
extern int array_queue_destory(struct array_queue *queue);
extern int array_queue_enqueue(struct array_queue *queue, void *in_data);
extern int array_queue_dequeue(struct array_queue *queue, void *out_data);

extern void array_queue_test(void);

四、创建顺序队列

1、队列头部动态创建

/**
 * dynamically creat and init an array queue.
 * 
 * @param size: array size
 * @param tpsz: data type size
 * @return result: array queue or NULL
 */
struct array_queue* array_queue_creat(int size, int tpsz)
{
    struct array_queue *queue = NULL;

    if (size <= 0 || tpsz <= 0)
        return NULL;

	/* malloc an array queue struct */
    queue = ARRAY_QUEUE_MALLOC(sizeof(*queue));
    if (queue == NULL)
        return NULL;
	
	/* calloc an array queue */
	void *p = ARRAY_QUEUE_CALLOC(1, (size * tpsz));
	if (p == NULL)
        return NULL;

    queue->size = size;
    queue->num = 0;
    queue->head = 0;
    queue->tail = 0;
    queue->tpsz = tpsz;
    queue->p = p;
    
    return queue;
}

2、队列头部静态创建

/**
 * init a static array queue.
 * 
 * @param queue: 
 * @param size: array size
 * @param tpsz: array data type length
 * @return -1:queue is null or malloc fail
 *          0:success
 */
int array_queue_init(struct array_queue *queue, int size, int tpsz)
{
	if (queue == NULL)
        return -1;
	
	/* calloc an array queue */
	void *p = ARRAY_QUEUE_CALLOC(1, (size * tpsz));
	if (p == NULL)
        return NULL;

    queue->size = size;
    queue->num = 0;
    queue->head = 0;
    queue->tail = 0;
    queue->tpsz = tpsz;
    queue->p = p;
	
	return 0;
}

五、出队列

/**
 * dequeue data from the array queue.
 * 
 * @param array_queue: array queue
 * @return -1: fail
 *         -2: queue is empty
 *          0: success
 */
int array_queue_dequeue(struct array_queue *queue, void *out_data)
{
	char *phead = NULL;

    if (queue == NULL)
        return -1;

	/* queue is empty */
	if(ARRAY_QUEUE_IS_EMPTY(queue))
        return -2;

	phead = queue->p;
    phead = phead + queue->tpsz * queue->head;
    memcpy(out_data, phead, queue->tpsz);
    queue->num--;
    queue->head = (queue->head + 1) % queue->size;

    return 0;
}

六、入队列

/**
 * enqueue data to the array queue.
 * 
 * @param queue: array queue
 * @return -1: fail
 *         -2: queue is full
 *          0: success
 */
int array_queue_enqueue(struct array_queue *queue, void *in_data)
{
    char *ptail = NULL;

    if (queue == NULL)
        return -1;

	/* queue is full */
    if(ARRAY_QUEUE_IS_FULL(queue))
        return -2;

	ptail = queue->p;
    ptail = ptail + queue->tpsz * queue->tail;
    memcpy(ptail, in_data, queue->tpsz);
    queue->num++;
    queue->tail = (queue->tail + 1) % queue->size;

    return 0;
}

七、队列删除

/**
 * delete array queue space.
 * 
 * @param array_queue: array queue
 * @return -1: fail
 *          0:success
 */
int array_queue_empty(struct array_queue *queue)
{
	if (queue == NULL)
		return -1;

    /* free array queue space */
    if (queue->p != NULL)
    {
        ARRAY_QUEUE_FREE(queue->p);
        queue->size = 0;
        queue->num = 0;
        queue->head = 0;
        queue->tail = 0;
        queue->tpsz = 0;
        queue->p = NULL;
    }
	
	return 0;
}

八、队列销毁

/**
 * delete and destroy an array queue.
 * 
 * @param array_queue: array queue
 * @return -1: fail
 *          0:success
 */
int array_queue_destory(struct array_queue *queue)
{
    if (array_queue_empty(queue) != 0)
        return -1;

    ARRAY_QUEUE_FREE(queue);
	queue = NULL;
		
    return 0;
}

九、验证程序

struct array_queue *array_queue_head;
int array_queue_w[6] = {11,22,33,44,55,66};
int array_queue_r[6] = {0};
void array_queue_test(void)
{
	array_queue_head = array_queue_creat(5, sizeof(int));
	
	array_queue_enqueue(array_queue_head, (void*)&array_queue_w[0]);
	array_queue_enqueue(array_queue_head, (void*)&array_queue_w[1]);
	array_queue_enqueue(array_queue_head, (void*)&array_queue_w[2]);
	array_queue_enqueue(array_queue_head, (void*)&array_queue_w[3]);
	array_queue_enqueue(array_queue_head, (void*)&array_queue_w[4]);
	array_queue_enqueue(array_queue_head, (void*)&array_queue_w[5]);
	
	array_queue_dequeue(array_queue_head, (void*)&array_queue_r[0]);
	array_queue_dequeue(array_queue_head, (void*)&array_queue_r[1]);
	array_queue_dequeue(array_queue_head, (void*)&array_queue_r[2]);
	array_queue_dequeue(array_queue_head, (void*)&array_queue_r[3]);
	array_queue_dequeue(array_queue_head, (void*)&array_queue_r[4]);
	array_queue_dequeue(array_queue_head, (void*)&array_queue_r[5]);
}

发布了35 篇原创文章 · 获赞 22 · 访问量 1146

猜你喜欢

转载自blog.csdn.net/m0_37845735/article/details/103330678