大家好,我是苏貝,本篇博客带大家了解队列,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
目录
- 一. 队列的概念及结构
- 二. 队列的实现
- 队列的结构体
- 初始化
- 销毁
- 队尾插入
- 队头删除
- 显示第一个节点的值
- 显示最后一个节点的值
- 是否为空
- 队列的大小
- 三. 模块化代码实现
- Queue.h
- Queue.c
- Test.c
- 结果演示
一. 队列的概念及结构
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的性质。FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
二. 队列的实现
1
队列的结构体
因为数组在头删的时候不方便,所以我们采用单链表来实现。
typedef int QDataType;typedef struct QueueNode
{struct Queue* next;QDataType val;
}QNode;typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;
2
初始化
因为我们要对队列进行初始化,所以实参要传Queue类型变量的地址,用一级指针来接收。因为实参(Queue类型变量的地址)不可能为NULL,所以对它断言(下面的接口同理)。
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
3
销毁
void QueueDestroy(Queue* pq)
{assert(pq);while (pq->phead){QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->ptail = NULL;pq->size = 0;
}
4
队尾插入
插入前要创建一个新节点,插入时还要判断队列是否为空,若为空则让pq->phead = pq->ptail = newnode。若不为空则只让pq->ptail ->next= newnode,再pq->ptail=pq->ptail->next
注意不要忘记pq->size++
void QueuePush(Queue* pq, QDataType x)
{assert(pq);//创建一个新节点QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->val = x;newnode->next = NULL;//插入if (pq->phead == NULL){pq->ptail = pq->phead = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}
5
队头删除
删除时要保证队列里有元素,所以对pq->phead断言,下面的显示第一个/最后一个节点的值同理
注意:当队列里只有一个元素时,删除后pq->phead指向NULL没错,但是此时pq->ptail是野指针,所以也要将pq->ptail置为NULL。不要忘记pq->size- -
void QueuePop(Queue* pq)
{assert(pq);assert(pq->phead);Queue* next = pq->phead->next;free(pq->phead);pq->phead = next;if (pq->phead == NULL){pq->ptail = NULL;}pq->size--;
}
6
显示第一个节点的值
QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->phead);return pq->phead->val;
}
7
显示最后一个节点的值
QDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->phead);return pq->ptail->val;
}
8
是否为空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL;
}
9
队列的大小
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}
三. 模块化代码实现
Queue.h
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>typedef int QDataType;typedef struct QueueNode
{struct Queue* next;QDataType val;
}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);
//是否为空
bool QueueEmpty(Queue* pq);
//队列的大小
int QueueSize(Queue* pq);
Queue.c
#include"Queue.h"//初始化
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}//销毁
void QueueDestroy(Queue* pq)
{assert(pq);while (pq->phead){QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}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");return;}newnode->val = x;newnode->next = NULL;//插入if (pq->phead == NULL){pq->ptail = pq->phead = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}//队头删除
void QueuePop(Queue* pq)
{assert(pq);assert(pq->phead);Queue* next = pq->phead->next;free(pq->phead);pq->phead = next;if (pq->phead == NULL){pq->ptail = NULL;}pq->size--;
}//显示第一个节点的值
QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->phead);return pq->phead->val;
}//显示最后一个节点的值
QDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->phead);return pq->ptail->val;
}//是否为空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL;
}//队列的大小
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}
Test.c
#include"Queue.h"int main()
{Queue p;QueueInit(&p);QueuePush(&p, 1);QueuePush(&p, 2);QueuePush(&p, 3);QueuePush(&p, 4);QueuePush(&p, 5);while (!QueueEmpty(&p)){printf("%d ", QueueFront(&p));QueuePop(&p);}QueueDestroy(&p);return 0;
}
结果演示
好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️