队列是一个非常经典的数据结构,是一种线性连续的存储方式,与它相类似的数据结构还有堆栈,线性表,数组这些数据结构,剩下的数据结构我会在后面的文章中一一介绍到。
那我们先来介绍一下队列中数据结构的特点:FIFO-先入先出
何为先入先出呢?就是最先入队列(存储在队列中)的元素最先出去,我们可以用一个图来说明:
因为队列是用来实现某些存储功能的我们当然要设计一些对队列操作方式:
首先是对队列的初始化:
我们首先应该知道一个队列应该有啥东西就可以方便我们操作队列,第一个就是数据的存储空间,在一个就是队列可以存储数据的容量,还有就是为了更加方便我们对队列中所存储元素的访问我们可以增加一个队列的头指针与尾指针。
知道这些后我们就可以现申请一个队列的控制头:
typedef struct QUEUE {
USER_TYPE *queue;
int capacity;
int front;
int rear;
int elementCount;
}QUEUE;
这个USER_TYPE就是用户自定义类型,我们可以自己写一个头文件把自己需要存储数据类型写在头文件里方便我们使用,capacity就是我们队列的容量,front和rear就是队列的头指针和尾指针,elemenCount就是队列中所存储的元素个数(这个可以有也可以没有看实际的使用需要)。
接下来就是对队列的初始化和销毁:
主要步骤就是申请空间,确定容量,将front,rear和elemenCount置为0。
boolean initQueue(QUEUE **queue, int capacity) {
if (queue == NULL || *queue != NULL) {
return FALSE;
}
*queue = (QUEUE *) calloc(sizeof(QUEUE),1);
if(*queue == NULL) {
return FALSE;
}
(*queue)->queue = (USER_TYPE *) calloc(sizeof(USER_TYPE),capacity);
if((*queue)->queue == NULL) {
free(*queue);
*queue = NULL;
return FALSE;
}
(*queue)->capacity = capacity;
(*queue)->front = 0;
(*queue)->rear = 0;
return TRUE;
}
在申请空间时要注意随时对所申请的空间进行正确性的判断,当申请失败时应该及时将之前申请的空间释放掉以免造成内存泄漏。这里使用了二阶指针而没有使用函数返回值返回一个指针来初始化队列也是为了防止使用者的不当使用而造成的内存泄漏。
下来就是销毁队列:
这个只有一个应该注意就是应该先销毁队列控制头中实际存储元素的空间,再去释放队列控制头。
void destoryQueue(QUEUE **queue) {
if(queue == NULL || *queue == NULL) {
return;
}
free((*queue)->queue);
free(*queue);
*queue = NULL;
}
在进行入队列和出队列的操作之前我们应该明白什么情况才能入队列什么情况才能出队列?
队列非满才可入,队列非空才可出,所以接下来的操作我们先不急着编写入队列和出队列,先写两个非常简单的函数判空与判满:
boolean queueIsFull(const QUEUE *queue) {
if(queue == NULL) {
return FALSE;
}
if (queue->capacity <= 0) {
return TRUE;
}
return queue->elementCount >= queue->capacity ? TRUE : FALSE;
}
boolean queueIsEmpty(const QUEUE *queue) {
if(queue == NULL) {
return FALSE;
}
if (queue->capacity <= 0) {
return TRUE;
}
return queue->elementCount == 0 ? TRUE : FALSE;
}
有了这两个函数我们接下来编写出入队列的函数就非常简单了:
boolean outputQueue(QUEUE *queue, USER_TYPE *data) {
if(queue == NULL || queueIsEmpty(queue)) {
return FALSE;
}
*data = queue->queue[queue->front];
queue->front++;
queue->elementCount--;
return TRUE;
}
boolean inputQueue( QUEUE *queue, USER_TYPE data) {
if (queue == NULL || queueIsFull(queue)) {
return FALSE;
}
queue->queue[queue->rear] = data;
queue->rear++;
queue->elementCount++;
return TRUE;
}
以上就是对队列的基本操作了,特别说明boolean类型实际上就是unsigned char类型,下面附上boolean的头文件定义:
#ifndef _TOOL_H_
#define _TOOL_H_
typedef unsigned char boolean;
#define TRUE 1
#define FALSE 0
#endif
有什么问题或者对代码有什么看法都可在面留言,谢谢阅读!