🎊这篇文章,我们来一起了解一下第四种线性表——队列的相关概念,当然,还有队列基本功能的实现
目录
一、概念及结构
🎡概念
队列也是一种特殊的线性表,只允许在一端进行插入数据的操作,在另一端进行删除数据的操作,由先进先出(FIFO)的原则,其中进行插入操作(入队列)的一端叫做队尾,进行删除操作(出队列)的一端叫做队头。
🎡结构
队列当然也可以用数组做链表来实现,但与栈相反,队列用链表来实现更好一些,因为在删除数据元素时,需要在队头进行,若使用数组实现,需要大量移动数据,会使效率变低。所以接下来我会用单链表来实现队列的基本功能。队列和日常生活中的排队是一个道理,先来的先出,后来的后出。
二、基本功能的实现
🎡头文件
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int QDataType;
typedef struct QListNode
{
QDataType data;
struct QListNode* next;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* front;
QNode* rear;
}Queue;
🎡函数声明
//菜单
void meum();
//初始化队列
void QueueInit(Queue* q);
//动态开辟一个结点
QNode* BuyQNode(QDataType x);
//队尾入队列
void QueuePush(Queue* q, QDataType data);
//队头出队列
void QueuePop(Queue* q);
//打印队列
void PrintQueue(Queue* q);
//获取队列头部元素
QDataType QueueFront(Queue* q);
//获取队列队尾元素
QDataType QueueBack(Queue* q);
//获取队列中有效元素个数
int QueueSize(Queue* q);
//检测队列是否为空
int QueueEmpty(Queue* q);
//销毁队列
void QueueDestroy(Queue* q);
🎡初始化队列
//初始化队列
void QueueInit(Queue* q)
{
assert(q);
q->front = q->rear = NULL;
}
🎡动态开辟一个结点
//动态开辟一个结点
QNode* BuyQNode(QDataType x)
{
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc");
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
🎡入队列
//队尾入队列
void QueuePush(Queue* q, QDataType data)
{
assert(q);
QNode* newnode = BuyQNode(data);
//如果队列为空
if (q->front == NULL)
{
q->front = q->rear = newnode;
}
else {
newnode->next = q->rear->next;
q->rear->next = newnode;
q->rear = newnode;
}
}
🎡出队列
//队头出队列
void QueuePop(Queue* q)
{
assert(q);
//如果队列为空
if (q->front == NULL)
{
return;
}
else {
QNode* node = q->front->next;
free(q->front);
q->front = node;
}
}
🎡打印队列
//打印队列
void PrintQueue(Queue* q)
{
assert(q);
QNode* cur = q->front;
while (cur != NULL)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}
🎡显示队头元素
//获取队头元素
QDataType QueueFront(Queue* q)
{
assert(q);
return q->front->data;
}
🎡显示队尾元素
//获取队尾元素
QDataType QueueBack(Queue* q)
{
assert(q);
return q->rear->data;
}
🎡判断队列长度
//获取队列中有效元素个数
int QueueSize(Queue* q)
{
assert(q);
int count = 0;
QNode* cur = q->front;
while (cur != NULL)
{
count++;
cur = cur->next;
}
return count;
}
🎡判断队列是否为空
//检测队列是否为空
int QueueEmpty(Queue* q)
{
assert(q);
return q->front == NULL;
}
🎡销毁队列
//销毁队列
void QueueDestroy(Queue* q)
{
assert(q);
if (q->front == NULL) return;
while (q->front)
QueuePop(q);
}
三、完整代码
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int QDataType;
typedef struct QListNode
{
QDataType data;
struct QListNode* next;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* front;
QNode* rear;
}Queue;
//菜单
void meum();
//初始化队列
void QueueInit(Queue* q);
//动态开辟一个结点
QNode* BuyQNode(QDataType x);
//队尾入队列
void QueuePush(Queue* q, QDataType data);
//队头出队列
void QueuePop(Queue* q);
//打印队列
void PrintQueue(Queue* q);
//获取队列头部元素
QDataType QueueFront(Queue* q);
//获取队列队尾元素
QDataType QueueBack(Queue* q);
//获取队列中有效元素个数
int QueueSize(Queue* q);
//检测队列是否为空
int QueueEmpty(Queue* q);
//销毁队列
void QueueDestroy(Queue* q);
//菜单
void meum()
{
printf("***********************************************************\n");
printf("* 1.入队列 2.出队列 3.打印队列 4.获取队头元素 *\n");
printf("* 5.获取队尾元素 6.计算队列长度 7.判断队列是否为空 0.退出 *\n");
printf("***********************************************************\n");
}
//初始化队列
void QueueInit(Queue* q)
{
assert(q);
q->front = q->rear = NULL;
}
//动态开辟一个结点
QNode* BuyQNode(QDataType x)
{
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc");
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
//队尾入队列
void QueuePush(Queue* q, QDataType data)
{
assert(q);
QNode* newnode = BuyQNode(data);
//如果队列为空
if (q->front == NULL)
{
q->front = q->rear = newnode;
}
else {
newnode->next = q->rear->next;
q->rear->next = newnode;
q->rear = newnode;
}
}
//队头出队列
void QueuePop(Queue* q)
{
assert(q);
//如果队列为空
if (q->front == NULL)
{
return;
}
else {
QNode* node = q->front->next;
free(q->front);
q->front = node;
}
}
//打印队列
void PrintQueue(Queue* q)
{
assert(q);
QNode* cur = q->front;
while (cur != NULL)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}
//获取队头元素
QDataType QueueFront(Queue* q)
{
assert(q);
return q->front->data;
}
//获取队尾元素
QDataType QueueBack(Queue* q)
{
assert(q);
return q->rear->data;
}
//获取队列中有效元素个数
int QueueSize(Queue* q)
{
assert(q);
int count = 0;
QNode* cur = q->front;
while (cur != NULL)
{
count++;
cur = cur->next;
}
return count;
}
//检测队列是否为空
int QueueEmpty(Queue* q)
{
assert(q);
if (q->front == q->rear)
return 1;
else return 0;
}
//销毁队列
void QueueDestroy(Queue* q)
{
assert(q);
if (q->front == NULL) return;
while (q->front)
QueuePop(q);
}
int main()
{
Queue q;
QueueInit(&q);
int select;
do {
meum();
printf("请输入选项:");
scanf("%d", &select);
switch (select)
{
//入队列
case 1:
printf("请输入要插入的元素:");
QDataType x;
scanf("%d", &x);
QueuePush(&q, x);
printf("入队列成功!\n");
break;
//出队列
case 2:
QueuePop(&q);
printf("出队列成功!\n");
break;
//打印队列
case 3:
PrintQueue(&q);
break;
//获取队头元素
case 4:
printf("队头元素为:%d\n", QueueFront(&q));
break;
//获取队尾元素
case 5:
printf("队尾元素为:%d\n", QueueBack(&q));
break;
//计算队列长度
case 6:
printf("队列长度为:%d\n", QueueSize(&q));
break;
//判断队列是否为空
case 7:
if (QueueEmpty(&q)) printf("队列为空!\n");
else printf("队列非空!\n");
break;
//退出
case 0:
QueueDestroy(&q);
printf("欢迎下次使用!\n");
break;
default:
printf("输入错误!\n");
}
} while (select);
return 0;
}
好了,这就是队列的基本功能和对应的实现方法,有问题的地方欢迎评论区留言,如果感觉有帮助,还请三连支持!!!