🐶博主主页:@ᰔᩚ. 一怀明月ꦿ
❤️🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++,数据结构
🔥座右铭:“不要等到什么都没有了,才下定决心去做”
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀
目录
🐰队列
🏡队列的概念
只允许在一端进行插入数据,在另一端进行删除数据操作的特殊的线性表,队列具有先进先出原则FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
DFS--深度优先遍历--递归/栈实现非递归
BFS--广度优先遍历--队列
队列实现:
1.数组队列
2.链式队列
注意:本文采用的是链式队列,因为队列满足先进先出原则,单链表的尾插和头删处理出队和出队的效率都比较的高
🏡队列的结构体定义
这里和以前实现的链表结构有点不同,以前使用一个结构体,队列这里使用了两个结构体,这是因为需求不同,以前我们只需要一个头指针就行,这里需要一个头指针和尾指针,还有队列数据的个数。我们在使用多个数据时,可以为其创建一个结构体方便我们管理数据。
typedef int QDataType; typedef struct QueueNode { struct QueueNode* next; QDataType data; }QNode; typedef struct Queue { QNode* phead; QNode* ptail; int size; }Queue;
🏡队列的初始化
void QueueInit(Queue* pq) { assert(pq); pq->phead=NULL; pq->ptail=NULL; pq->size=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; }
🏡进队列(尾插)
进队列实质就是单链表的尾插,但这里得两种情况,1.队列为空,我们让头指针和尾指针指向进队列的节点。2.队列不为空,和单链表的尾插一样
void QueuePush(Queue* pq,QDataType x) { assert(pq); QNode* newnode=(QNode*)malloc(sizeof(QNode)); if(newnode==NULL) { perror("malloc fail\n"); return; } newnode->data=x; if(pq->phead==NULL)//当链表为空的时候 { assert(!pq->ptail);//当链表为空的时候,pq->ptail也是空 pq->phead=newnode; pq->ptail=newnode; } //链表不为空的时候进队列插入数据(尾插) else { pq->ptail->next=newnode; pq->ptail=newnode; } pq->size++; }
🏡出队列(头删)
进队列实质就是单链表的头删,但这里得三种情况,1.队列为空,不需要进行从队列删除数据。2.队列只有一个元素时,将这个节点free掉,将头指针和尾指针置空。3.队列有多个元素时,和单链表的头删一样
void QueuePop(Queue* pq) { assert(pq); assert(!QueueEmpty(pq));//判断队列是否为空,断言为真程序继续 //一个节点的时候 //if(pq->phead->next==NULL) if(pq->phead==pq->ptail) { free(pq->phead); pq->phead=NULL; pq->ptail=NULL; } //多个节点的时候 else { //相当于头删 QNode* next=pq->phead->next; free(pq->phead); pq->phead=next; } pq->size--; }
🏡队头元素
QDataType QueueFront(Queue* pq) { assert(pq); assert(!QueueEmpty(pq));//判断队列是否为空,断言为真程序继续 return pq->phead->data; }
🏡队尾元素
其实本不需要返回队尾元素的,但是为了C++中栈对齐而且方便做某些OJ题
QDataType QueueBack(Queue* pq) { assert(pq); assert(!QueueEmpty(pq)); return pq->ptail->data; }
🏡返回队列的数据个数
int QueueSize(Queue* pq) { assert(pq); return pq->size; }
🏡判断队列是否为空
bool QueueEmpty(Queue* pq) { assert(pq); return pq->phead==NULL; }
🏡队列的源码
🌸main文件
#include "test.h" void test1(void) { Queue q1; QueueInit(&q1); QueuePush(&q1, 1); QueuePush(&q1, 2); QueuePush(&q1, 3); QueuePush(&q1, 4); printf("size:%d\n",QueueSize(&q1)); while(!QueueEmpty(&q1)) { printf("%d ",QueueFront(&q1)); QueuePop(&q1); } printf("\n"); QueueDestroy(&q1); } int main() { test1(); return 0; }
🌸test.h文件
#ifndef test_h #define test_h #include <stdio.h> #include<stdlib.h> #include<stdbool.h> #include<assert.h> #endif /* test_h */ typedef int QDataType; typedef struct QueueNode { struct QueueNode* next; QDataType data; }QNode; typedef struct Queue { QNode* phead; QNode* ptail; int size; }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);
🌸test.c文件
#include "test.h" void QueueInit(Queue* pq) { assert(pq); pq->phead=NULL; pq->ptail=NULL; pq->size=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; } void QueuePush(Queue* pq,QDataType x) { assert(pq); QNode* newnode=(QNode*)malloc(sizeof(QNode)); if(newnode==NULL) { perror("malloc fail\n"); return; } newnode->data=x; if(pq->phead==NULL)//当链表为空的时候 { assert(!pq->ptail);//当链表为空的时候,pq->ptail也是空 pq->phead=newnode; pq->ptail=newnode; } //链表不为空的时候进队列插入数据(尾插) else { pq->ptail->next=newnode; pq->ptail=newnode; } pq->size++; } void QueuePop(Queue* pq) { assert(pq); assert(!QueueEmpty(pq));//判断队列是否为空,断言为真程序继续 //一个节点的时候 //if(pq->phead->next==NULL) if(pq->phead==pq->ptail) { free(pq->phead); pq->phead=NULL; pq->ptail=NULL; } //多个节点的时候 else { //相当于头删 QNode* next=pq->phead->next; free(pq->phead); pq->phead=next; } pq->size--; } QDataType QueueFront(Queue* pq) { assert(pq); assert(!QueueEmpty(pq));//判断队列是否为空,断言为真程序继续 return pq->phead->data; } QDataType QueueBack(Queue* pq) { assert(pq); assert(!QueueEmpty(pq)); return pq->ptail->data; } bool QueueEmpty(Queue* pq) { assert(pq); return pq->phead==NULL; } int QueueSize(Queue* pq) { assert(pq); return pq->size; }
🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸