队列的概念及结构
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表。队列中的数据元素遵守 先进先出 的原则。FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾。
出队列:进行删除操作的一端称为队头。
队列的实现
队列可以数组或链表的结构实现,但因为数组结构出队列时需要在数组头上出数据,效率较低,所以使用链表结构实现更优一些。
队列的定义
typedef int QDatatype;
typedef struct QueueNode //队列结点的定义
{
struct QueueNode* next;
QDatatype data;
}QNode;
typedef struct Queue //定义队列
{
QNode* head;
QNode* tail;
int size; //队列内结点个数
}Queue;
//两层封装来定义队列,为了使队列的头尾均可直接访问
初始化队列
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
销毁队列
void QueueDestroy(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* next = cur->next; //存储即将销毁的结点的下一个结点
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
入队列
void QueuePush(Queue* pq, QDatatype x)
{
QNode* newnode = (QNode*)malloc(sizeof(QNode)); //新建结点
if (newnode == NULL)
{
perror("malloc fail");
exit(1);
}
newnode->data = x;
newnode->next = NULL;
if (pq->head == NULL) //头结点入队
{
assert(pq->tail == NULL);
pq->head = pq->tail = newnode;
}
else //非头结点入队
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++; //结点个数+1
}
出队列
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->head != NULL);
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
if (pq->head == NULL) //条件为真代表队列已为空,那么tail要置空,防止出现野指针
pq->tail = NULL;
pq->size--;
}
查看队列数据个数
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
判断队列是否为空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->size == 0;
}
查看队头元素数据
QDatatype Queuefront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
}
查看队尾元素数据
QDatatype QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
}