目录
队列的概念及结构
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出
FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头
队列的实现
此处选择用链表实现,链表的结构会比数组更优化,且方便进行数据加入Push和删除Pop
队列的结构体定义
typedef int QDataType;
typedef struct QueueNode //整体框架,一个元素的结构
{
struct QueueNode* next;//结构体指针内又存放着其他数据,为单链表
QDataType data;
}QNode;
//内部结构
typedef struct Queue//队列更适合用链式结构去实现,队列的结构
{
QNode* phead;//出数据 用QNode修饰,那么说明phead也可以指向下一个元素next和储存data
QNode* ptail;//入数据
int size;//记录大小,虽然链表没有大小限制,但是可以方便读取大小,不需要遍历
}Queue;
队列的初始化
void QueueInit(Queue* pq)
{
assert(pq);
pq->phead = NULL; //头尾都置空
pq->ptail = NULL;
pq->size = 0;//总体数据数为0
}
判断是否为空
bool QueueEmpty(Queue* pq)
{
assert(pq);
/*return pq->phead==NULL&&pq->phead==NULL*/ //但其实如果头为空,尾部基本也会为空
return pq->size == 0;//为空,那么元素数为0,否则不为0
}
队列的摧毁
void QueueDestroy(Queue* pq)
{
assert(pq);//断言结构体是否为空
QNode* cur=pq->phead;
while(cur)
{
QNode* next=cur->next;
free(cur);
cur=next;
}
pq->phead=pq->ptail=NULL;
pq->size=0;//数据置0
}
队列的数据加入
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode=(QNode*)malloc(sizeof(QNode));
if(newnode==NULL)
{
perror("malloc falii");
return;
}
newnode->data=x;
newnode->next=NULL;
if(pq->ptail==NULL)//第一个元素
{
assert(pq->phead==NULL)
pq->phead=pq->ptail=newnode;
}
else
{
pq->ptail->next=newnode;
pq->ptail=newnode;//newnode成为新的尾部
}
pq->size++;//队列数+1
}
队列数据的删除
队列数的数据要删除头元素
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
if(pq->phead->next==NULL)//此时为一个结点,那么就直接释放
{
free(pq->phead);
pq->phead=pq->ptail=NULL;
}
else{
QNode* cur=pq->phead->next;
free(pq->phead);
pq->phead=cur;
}
pq->size--;//删除需要减少数据
}
队列数据的提出
由于是队列,所以需要从头部取
QDataType QueueFront(Queue* pq)//取头部
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->ptail->data;
}
队尾数据的提取
QDataType QueueBack(Queue* pq)//取队尾
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->ptail->data;
}
队列数据数的提取
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;//返回元素个数
}
由上,队列的代码实现其实很简单,仅在一开始结构体的建立会比较困难
Queue.h
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int QDataType;
typedef struct QueueNode //整体框架,一个元素的结构
{
struct QueueNode* next;//结构体指针内又存放着其他数据,为单链表
QDataType data;
}QNode;
//内部结构
typedef struct Queue//队列更适合用链式结构去实现,队列的结构
{
QNode* phead;//出数据 用QNode修饰,那么说明phead也可以指向下一个元素next和储存data
QNode* ptail;//入数据
int size;//记录大小,虽然链表没有大小限制,但是可以方便读取大小,不需要遍历
}Queue;
//为什么不用二级指针——指针放在结构体内,改变结构体,指针是结构体的成员,并不是结构体指针
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);//头删
bool QueueEmpty(Queue* pq);
QDataType QueueFront(Queue* pq);//取头部
QDataType QueueBack(Queue* pq);//取队尾
int QueueSize(Queue* pq);