目录
一、队列的概念和结构
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有 先进先出FIFO (First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头;
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。( 一般如果采用顺序栈,常设计成循环队列的形式,这个放到下一期博客说 )数组实现队列:![]()
链表实现队列:
二、链式结构表示队列
用链式结构表示队列,我们需要两个指针,一个控制队尾,一个控制队头,方便数据入队和出队;如果不控制队尾,那么在入数据的时候,我们就需要先去找到队尾(即链表的尾),这就很麻烦;
typedef int QDataType; //链表的结构 typedef struct QueueNode { QDataType data; struct QueueNode* next; }QNode; typedef struct Queue { //都是链表的指针,head和tail都可以去访问链表,在处理入队和出队上就很方便了 QNode* head;//队头 QNode* tail;//队尾 }Queue;
三、队列各个接口函数的实现
1.队列的初始化
//队列的初始化
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
}
2.队尾入队列(尾插)
队列相当于在单链表的基础上加了一些限制,并且多了头尾指针的控制,在进行尾插的时候相比单链表快了很多,单链需要循环判断找尾,而队列可以直接找到尾 ;
如果单链表还不太清楚的同学可以复习一下:https://blog.youkuaiyun.com/sjsjnsjnn/article/details/123920224?spm=1001.2014.3001.5501
//队尾入队列
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
newnode->data = x;
newnode->next = NULL;
if (pq->head == NULL)
{
//第一个元素入队
pq->head = pq->tail = newnode;
}
else
{
//数据队尾入
pq->tail->next = newnode;
//tail控制队尾(记住新的尾)
pq->tail = newnode;
}
}
3.队头出队列(头删)
在头删的时候要注意,当头删删到队尾时候,此时head和tail指向的同一块空间,要记得把tail也要释放了;
//队头出队列
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
//此时head和tail同时指向最后一个空间,释放head后,要注意也要把tail释放了
if (pq->head == NULL)
{
pq->tail = NULL;
}
}
4.取队头的数据
//取队头的数据
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));//判断队列是否为空
return pq->head->data;//直接返回头指针所指向的数据
}
5.取队尾的数据
//取队尾的数据
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));//判断队列是否为空
return pq->tail->data;//直接返回尾指针所指向的数据
}
6.计算队列的数据个数
//计算队列的数据个数
int QueueSize(Queue* pq)
{
assert(pq);
int n = 0;
QNode* cur = pq->head;
while (cur)
{
++n;
cur = cur->next;
}
return n;
}
7.判断队列是否为空
//判断队列是否为空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL;
}
四、源代码
Queue.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int QDataType;
typedef struct QueueNode
{
QDataType data;
struct QueueNode* next;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
}Queue;
//队列的初始化
void QueueInit(Queue* pq);
//队列的销毁
void QueueDestroy(Queue* pq);
//队尾入队列
void QueuePush(Queue* pq, QDataType x);
//队头出队列
void QueuePop(Queue* pq);
//取队头的数据
QDataType QueueFront(Queue* pq);
//取队尾的数据
QDataType QueueBack(Queue* pq);
//计算队列的数据个数
int QueueSize(Queue* pq);
//判断队列是否为空
bool QueueEmpty(Queue* pq);
Queue.c
#include "Queue.h"
//队列的初始化
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
}
//队列的销毁
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;
}
//队尾入队列
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
newnode->data = x;
newnode->next = NULL;
if (pq->head == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}
//队头出队列
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
//此时head和tail同时指向最后一个空间,释放head后,要注意也要把tail释放了
if (pq->head == NULL)
{
pq->tail = NULL;
}
}
//取队头的数据
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;
}
//计算队列的数据个数
int QueueSize(Queue* pq)
{
assert(pq);
int n = 0;
QNode* cur = pq->head;
while (cur)
{
++n;
cur = cur->next;
}
return n;
}
//判断队列是否为空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL;
}
Test.c
#include "Queue.h"
void QueueTest1()
{
Queue q;
QueueInit(&q);
//数据入队
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
QueuePush(&q, 5);
QueuePush(&q, 6);
QueuePush(&q, 7);
QueuePush(&q, 8);
//1 2 3 出队列
//QueuePop(&q);
//QueuePop(&q);
//QueuePop(&q);
while (!QueueEmpty(&q))
{
QDataType front = QueueFront(&q);
printf("%d ", front);
QueuePop(&q);
}
QueueDestroy(&q);
}
int main()
{
QueueTest1();
return 0;
}