1.队列的结构与概念
![](https://i-blog.csdnimg.cn/blog_migrate/d5024861ccc51628365a6125b4d48b17.png)
2.队列的代码实现
![](https://i-blog.csdnimg.cn/blog_migrate/95fb0a9cf72b451e1620ea9a6fac3d1b.png)
2.1队列——链式结构体
// 链式结构:表示队列typedef int QDataType ; //定义数据类型
typedef struct QListNode
{
struct QListNode* next; //记录下一个指针的地址
QDataType data; //记录数据
}QNode;// 队列的结构 记录
typedef struct Queue
{
QNode* phead; //记录头部指针的位置
QNode* tail; //记录末尾指针的位置
int size; //记录数据个数
}Queue;
2.2队尾入队列
void QueuePush(Queue* q, QDataType data)
{
assert(q); //判断q的有效性;
QNode* set = (QNode*)malloc(sizeof(QNode)); //开辟一个QNode数据的空间
if (!set) //判断set是否开辟空间成功
{
printf("queuePush malloc err...."); //失败即报错返回
return;
}
set->data = data; //开辟空间成功后,把数据data写入
set->next = NULL; //把set的next指针置空
if (q->phead == NULL) //当phead为空的时候,说明这个时候是第一个数据入 队列,头部指针和尾部指针都指向一个地址
{
q->phead = q->tail = set; //所以q指向的phead与tail的地址相等与set;
}
else //当不是第一个数据的时候,我们需要另外判断
{
q->tail->next = set; //将set插入在队列尾部,完成入队
q->tail = q->tail->next; //因为新插入数据,这里需要更新一下尾指针的地址。
}
q->size++; //完成入队操作后,size别忘了要自增一下
}
2.3队列首部出队列
void QueuePop(Queue* q)
{
assert(q);
assert(q->phead); //这里需要判断一下phead的有效性,当没有数据的时候警告一下
QNode* set = q->phead; //创建一个指针记录一下phead的当前地址
q->phead = q->phead->next; //把phead指向的地址更新一下
free(set); //然后把set记录数据的空间给释放掉,完成出队操作
set = NULL;
//如果首元素free掉后,tail也应该置为null
if (q->phead == NULL) //当队列里完成出队操作后,队列里已经没有任何数据时
{ //需要把tail指向的地址给更新置空,方便下次操作
q->tail = NULL;
}
q->size--; //数据个数减1;
}
2.4 获取队列头部元素
QDataType QueueFront(Queue* q)
{
assert(q);
assert(q->phead); //需要判断一下phead的有效性
return q->phead->data; //直接返回phead指向的data(首部数据元素)
}
2.5获取队列队尾元素
QDataType QueueBack(Queue* q)
{
assert(q);
assert(q->tail); //需要判断一下tail的有效性
return q->tail->data; //直接返回tail指向的data(尾部数据元素)
}
2.6获取队列中有效元素个数
int QueueSize(Queue* q)
{
assert(q);
return q->size; //直接返回q指向的size(记录的数据个数)
}
2.7检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* q)
{
assert(q);
return q->phead == 0; //直接返回判断结果;
}
2.8销毁队列
void QueueDestroy(Queue* q)
{
assert(q);
QNode* set = q->phead;
while (set) //与链表释放数据一样,释放直到set==null结束;
{
QNode* nex = set->next;
free(set);
set = nex;
}
q->tail = q->phead=NULL; //释放的时候,把Queue里记录的数据给更新回档一下
q->size = 0;
}
3.代码文本
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int QDataType ;
// 链式结构:表示队列
typedef struct QListNode
{
struct QListNode* next;
QDataType data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* phead;
QNode* tail;
int size;
}Queue;
// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QDataType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QDataType QueueFront(Queue* q);
// 获取队列队尾元素
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);
// 初始化队列
void QueueInit(Queue* q)
{
//断言q
assert(q);
q->phead = q->tail = NULL;
q->size = 0;
}
// 队尾入队列
void QueuePush(Queue* q, QDataType data)
{
assert(q);
QNode* set = (QNode*)malloc(sizeof(QNode));
if (!set)
{
printf("queuePush malloc err....");
return;
}
set->data = data;
set->next = NULL;
if (q->phead == NULL)
{
q->phead = q->tail = set;
}
else
{
q->tail->next = set;
q->tail = q->tail->next;
}
q->size++;
}
// 队头出队列
void QueuePop(Queue* q)
{
assert(q);
assert(q->phead);
QNode* set = q->phead;
q->phead = q->phead->next;
free(set);
set = NULL;
//如果首元素free掉后,tail也应该置为null
if (q->phead == NULL)
{
q->tail = NULL;
}
q->size--;
}
// 获取队列头部元素
QDataType QueueFront(Queue* q)
{
assert(q);
assert(q->phead);
return q->phead->data;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q)
{
assert(q);
assert(q->tail);
return q->tail->data;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q)
{
assert(q);
return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* q)
{
assert(q);
return q->phead == 0;
}
// 销毁队列
void QueueDestroy(Queue* q)
{
assert(q);
QNode* set = q->phead;
while (set)
{
QNode* nex = set->next;
free(set);
set = nex;
}
q->tail = q->phead = NULL;
q->size = 0;
}
4.总结
队列的核心思想是先进先出。